【问题标题】:Rails 4 ActiveRecord query join and order by a user's number of association recordsRails 4 ActiveRecord 查询连接并按用户的关联记录数排序
【发布时间】:2014-01-14 21:46:08
【问题描述】:

我有 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(gender: "M") .joins(:user) .where("users.activation_state = '活动'") .order('user_activities.updated_at DESC') .includes([:user, user: [ :subscription ]]).order('user_photos_count DESC')

【问题讨论】:

    标签: sql ruby-on-rails activerecord


    【解决方案1】:

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

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

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

    order("user_photos_count desc")
    

    【讨论】:

      【解决方案2】:

      我可能会这样做:

      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)
      

      【讨论】:

      • 谢谢,这很好,我开始这样做了,但由于前人编码它的方式,我需要一个 UserActivity 对象 - 否则我将不得不重构一些视图。但我确实使用了计数器缓存。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多