Rails 4 ActiveRecord通过用户的关联记录数查询连接和排序

时间:2014-01-14 21:46:08

标签: sql ruby-on-rails activerecord

我有3个模型,UserActivity,User和UserPhoto。

User
  has_many :user_photos, dependent: :destroy
  has_one :user_activity, dependent: :destroy
  has_one :subscription, dependent: :destroy

UserActivity
  belongs_to :user
  delegate :user_photos, to: :user

UserPhoto
    belongs_to :user  

我想获取所有“有效”且订阅的用户,并在他们上次参与“用户活动”时订购,并根据他们拥有的照片数量进行订购。

当前,我有:

UserActivity.where(gender: "M")
            .joins(:user)
            .where("users.activation_state = 'active'")
            .order('user_activities.updated_at DESC')
            .includes([:user, user: [ :subscription ]])  

这将返回按上次活动更新排序的所有活动用户。

我已经尝试添加查询片段,例如“.joins(:user_photo).order('user.user_photos.length DESC')”,这会导致上述情况发生阻塞。有人能指出我正确的方向吗?

编辑/更新:我使用了以下用户建议的计数器缓存,结果是:

UserActivity.where(性别:“M”)             .joins(:用户)             .where(“users.activation_state ='active'”)             .order('user_activities.updated_at DESC')             .includes([:user,user:[:subscription]])。order('user_photos_count DESC')

2 个答案:

答案 0 :(得分:0)

您需要通过子查询进行排序,该子查询检索子记录的计数,例如:

order("(select count(*) from user_photos where user_photos.user_id = users.id) desc")

但是,在users表上维护user_photos的计数器缓存会更有效。

order("user_photos_count desc")

答案 1 :(得分:0)

我可能会这样做:

class UserPhoto
  belongs_to :user, counter_cache: true
end

class User
  # You need extra column here: user_photos_count

  has_many :user_photos, dependent: :destroy
  has_one :user_activity, dependent: :destroy
  has_one :subscription, dependent: :destroy

  scope :active, -> { where(activation_state: 'active') }
  scope :with_subscription, -> { joins(:subscription) }
end

然后简单地

User.active.with_subscription.joins(:user_activities, :user_photos).order('user_activities.updated_at DESC').order(user_photos_count: desc)