ruby on rails - rails表单验证 - 是否有可能使使用:连接选项加载的行的ActiveRecord创建对象?



rails数据库 (2)

你遇到的问题是你使用ActiveRecord的方式,而不是“应该”使用。 我的意思是说你正在编写你自己的sql,这使得AR把所有的控制权都放弃了。

如果你想要AR来处理所有的事情,你应该尽量少用自己的SQL来使用它。 看起来你想知道哪个用户的AbuseReports数量最多。 尝试这样的事情:

some_user.abuse_reports.count

得到abuse_reports的数量

https://src-bin.com

我需要做这样的事情

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或游戏的对象 - 它只是返回一堆行。 当我从视图中引用这些对象时,会再次加载它们。 有没有办法来解决这个问题? 或者某种方式来获得这种行为,而不使用:连接?


Answer #1

首先,你应该使用: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。