我需要做这样的事情
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或游戏创建对象--它只返回一堆行。当我从视图中引用这些对象时,它会再次加载它们。有没有办法解决这个问题?或者使用某种方法来获得此行为,而不使用:join?
发布于 2009-02-14 22:46:40
首先,您应该真正使用:include而不是:join
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,使关系型数据库的运行更轻松,查询速度更快)。在设置计数器缓存之后,最后可以修改上面的内容:
User.find(:all, :include => [ :abuse_reports, :abused_games ], :order => 'users.abused_games_count DESC, users.abuse_reports_count DESC')这最终将在一条简单的SQL语句中检索您的ActiveRecords。
发布于 2009-02-14 18:08:18
你遇到的问题是,你使用ActiveRecord的方式不是“应该”使用的。我的意思是,你正在编写自己的sql,这使得AR放弃了对你的所有控制。
如果你想让AR处理所有的事情,你应该尽量少使用你自己的SQL语句。看起来你想知道哪个用户拥有最多的AbuseReports。尝试如下所示:
some_user.abuse_reports.count获取abuse_reports的计数
https://stackoverflow.com/questions/549374
复制相似问题