我在这里有这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
我想让所有与会者参加特定的派对,并邀请那些邀请最多人参与的人。
我该怎么做?
感谢您的帮助。
答案 0 :(得分:2)
几种可能的解决方案:
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)
优点:很好,不言自明。无需从数据库加载邀请。易于排队的协会。
缺点:您需要更新所有记录&#39;在开始使用它之前使用counter_cache:
Attendees.includes(:invitations).each { |att| att.invitation_count = att.invitation.to_a.size }
在此之后,rails将负责将列保持与一些与参加者启动相关联。