首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否可以让ActiveRecord为使用:joins选项加载的行创建对象?

是否可以让ActiveRecord为使用:joins选项加载的行创建对象?
EN

Stack Overflow用户
提问于 2009-02-14 17:06:42
回答 2查看 480关注 0票数 5

我需要做这样的事情

代码语言:javascript
复制
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?

EN

回答 2

Stack Overflow用户

发布于 2009-02-14 22:46:40

首先,您应该真正使用:include而不是:join

代码语言:javascript
复制
User.find(:all, :include => { :abuse_reports => [ :game ] }, :order => )

或者,在您的情况下,尝试

代码语言:javascript
复制
User.page(params[:page], :include => { :abuse_reports => [ :game ] })

这将为您执行连接,并在一次操作中检索记录。

现在,这可能会为您多次检索给定的游戏记录(如果同一个游戏通过多个报告绑定到一个用户)。如果您的游戏记录很大,您可以减少应用程序和RDBMS之间交换的数据量,如下所示:

代码语言:javascript
复制
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,使关系型数据库的运行更轻松,查询速度更快)。在设置计数器缓存之后,最后可以修改上面的内容:

代码语言:javascript
复制
User.find(:all, :include => [ :abuse_reports, :abused_games ], :order => 'users.abused_games_count DESC, users.abuse_reports_count DESC')

这最终将在一条简单的SQL语句中检索您的ActiveRecords。

票数 11
EN

Stack Overflow用户

发布于 2009-02-14 18:08:18

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

如果你想让AR处理所有的事情,你应该尽量少使用你自己的SQL语句。看起来你想知道哪个用户拥有最多的AbuseReports。尝试如下所示:

代码语言:javascript
复制
some_user.abuse_reports.count

获取abuse_reports的计数

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/549374

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档