我需要做这样的事情
class User < ActiveRecord::Base
has_many :abuse_reports
end
class AbuseReport < ActiveRecord::Base
belongs_to :abuser, :class_name => 'User', :foreign_key => 'abuser_id'
belongs_to :game
end
class Game < ActiveRecord::Base
has_many :abuse_reports
end
@top_abusers = User.page(params[:page],
:joins => [
'JOIN abuse_reports ON users.id = abuse_reports.abuser_id',
'JOIN games ON games.id = abuse_reports.game_id'
],
:group => 'users.id',
:select => 'users.*, count(distinct games.id) AS game_count, count(abuse_reports.id) as abuse_report_count',
:order => 'game_count DESC, abuse_report_count DESC'
)
这有效,但不会为 AbuseReports 或 Games 创建对象 - 它只会返回一堆行。当我从我的 View 中引用这些对象时,它会再次加载它们。有没有办法来解决这个问题?或者不使用 :joins 就能获得这种行为的某种方式?
最佳答案
首先,你应该真正使用 :include 而不是 :joins
User.find(:all, :include => { :abuse_reports => [ :game ] }, :order => )
或者,根据您的情况,尝试
User.page(params[:page], :include => { :abuse_reports => [ :game ] })
这将为您执行连接并一次性检索记录。
现在,这可能会为您多次检索给定的游戏记录(如果同一个游戏通过多个报告与用户相关联。)如果您的游戏记录很大,您可以减少应用和应用之间交换的数据量RDBMS 如下:
class User < ActiveRecord::Base
has_many :abuse_reports
has_many :abused_games, :through => :abuse_reports
end
...
User.find(:all, :include => [ :abuse_reports, :abused_games ])
最后,您还想检索计数并进行相应排序。查看http://railscasts.com/episodes/23了解如何将计数器缓存添加到实际的事件记录中(计数器缓存简化了 SQL 并使 RDBMS 的生活更轻松,查询运行得更快)。设置计数器缓存后,您最终可以更改上面的内容来执行以下操作:
User.find(:all, :include => [ :abuse_reports, :abused_games ], :order => 'users.abused_games_count DESC, users.abuse_reports_count DESC')
这最终将在一个单个、简单 SQL 语句中检索您的 ActiveRecords。
关于ruby-on-rails - 是否可以让 ActiveRecord 为使用 :joins option? 加载的行创建对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/549374/