[英]Ordering results with ActiveRecord and Postgres with has_many through statement
我在这里有以下3个模型:
class User < ActiveRecord::Base
has_many :parties, foreign_key: 'organizer_id'
has_many :invitations, foreign_key: 'attendee_id'
end
class Party < ActiveRecord::Base
belongs_to :organizer, class_name: 'User'
has_many :invitations
has_many :attendees, through: :invitations
end
class Invitation < ActiveRecord::Base
belongs_to :party
belongs_to :attendee, class_name: 'User'
belongs_to :inviter, class_name: 'User'
end
我想让一个特定聚会的所有参与者都可以按邀请最多的人进行排序。
我该怎么做呢?
谢谢你的帮助。
几个可能的解决方案:
party.attendees.joins(:invitations).select('parties.*', 'COUNT(DISTINCT invitations.id) as invitation_count').group('parties.id').order('invitation_count')
优点:可能有效
缺点:这很丑陋,无法解释自身,您最终将很难查询关系。 宁可避免。
在应用程序级别对其进行排序:
party.attendees.includes(:invitations).sort_by {|att| att.inivtaions.to_a.size }
优点:更清楚您在做什么
缺点:返回不可查询数组,而不是关系。 仍然需要解释为什么要调用to_a
(以避免N + 1问题)。
添加一个额外的列invitations_count
给与会者表,并添加counter_cache: true
的belongs_to :attendee
在你的邀请模式。 利润!
party.attendees.order(:invitations_count)
优点:不错,不言自明。 无需从数据库加载邀请。 容易查询的关联。
缺点:在开始使用它之前,您需要更新所有记录的counter_cache:
Attendees.includes(:invitations).each { |att| att.invitation_count = att.invitation.to_a.size }
之后,Rails将负责使列与与参加者邀请相关联的许多列保持同步。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.