【问题标题】:Includes not allowing outer join and count on child table包括不允许外连接和子表计数
【发布时间】:2014-06-07 14:13:12
【问题描述】:
class Course < ActiveRecord::Base
  has_many :registrations

  delegate :count, to: :registrations, prefix: true
end

class Registration < ActiveRecord::Base
  belongs_to :course
end

在我的课程索引视图中,我显示了每条记录的注册数。对此的最佳做法是什么?将 includes(:registrations) 与委托的 registrations_count 方法一起使用(在控制台中)看起来比在主查询中执行数据库计数要慢。

我想显示所有记录,所以我不能使用 INNER join()。使用 include() 如下所示会出现错误PG::GroupingError: ERROR: column "registrations.id" must appear in the GROUP BY clause or be used in an aggregate function 我尝试在 :registrations 上添加 where 子句,但它仍然出错:

Course.includes(:registrations).group("courses.id").select("courses.*, COUNT(registrations.id) as registrations_count")

必须如下指定外连接是否正确?

Course.joins('LEFT OUTER JOIN registrations ON registrations.course_id = courses.id').select('courses.*, COUNT(registrations.id) as registrations_count').group('courses.id')

最后一个查询确实有效,但我觉得我所做的应该是相当标准的,所以我想确保我总体上采取了正确的方法。

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    在我的课程索引视图中,我显示了每条记录的注册计数。对此的最佳做法是什么?

    counter_caching 是计算association 对象的最佳选择。 Rails 中的计数器缓存只是一个额外的列,用于跟踪关联模型的数量。

    你只需要这样做

    belongs_to :course , counter_cache: true
    

    然后你可以简单地做到这一点

    @course.registrations_count
    

    RailsCast了解更多信息

    看起来你错过了includesjoinsLearn here之间的区别

    对我来说这很好。

    Course.joins('LEFT OUTER JOIN registrations ON registrations.course_id = courses.id').select('courses.*, COUNT(registrations.id) as registrations_count').group('courses.id')
    

    【讨论】:

    • 我知道包含 v 连接的区别只是让左外连接需要在此处明确写入感到惊讶。但如果使用 counter_cache 则不是 :) 谢谢。看起来它可以通过@course.registrations_count 列访问,而不是registrations.size?
    猜你喜欢
    • 2023-02-03
    • 1970-01-01
    • 1970-01-01
    • 2018-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多