从标题开始,我想显示一个用户列表-按最近创建的has_many
关联排序。
User
has_many :interactions
我需要能够显示一个包含用户的表-按他们最后的
interaction
日期排序,该表还应该显示交互的总数(在数据库中不使用counter_cache
),并且还包括分页。我们之前使用的(不起作用的)作用域是沿着
User.with_a_bunch_of_scopes.includes(:interactions).order("interactions.created_at DESC")
我已经删除了大部分尝试,但我尝试使用
MAX(interactions.created_at)
并按其他各种属性分组,但没有成功。分页是这里最困难的部分-似乎,除非我弄错了什么,否则使用
:includes
/LEFT OUTER JOIN
会适当地限制每个交互只有一个用户,但是,似乎其他交互正在限定范围。我正在使用Kaminari gem,但是能够使用limit
和offset
复制问题例如:
Interaction Users sorted_by interactions.created_at
-------------------------
User 1
User 1
User 2
User 3
User 2
User 2
User 4
User 1
User 4
User 3
User 5
给我们:
Page # per 4
Page 1 - [1, 2, 3, 4]
Page 2 - [2, 4, 1, 3]
Page 3 - [4, 3, 5]
然而,我们希望:
Page # per 4
Page 1 - [1, 2, 3, 4]
Page 2 - [5]
它只正确地包含每个用户一次,但是,它包含页面上的用户,而这些用户已经包含在以前的页面上。
任何帮助都非常感谢。时不时地回到这个问题上,试图解决一段时间,却永远无法让它像预期的那样回归。
最佳答案
假设您需要一个用户对象数组,并且由于您正在动态生成每个用户的交互计数,因此您可以通过映射所有排序交互的每个唯一用户的as_json
来执行此操作(以及分页):
User.includes(:interactions).order('interactions.created_at desc').uniq.page(params[:page]).per(4).map(&:as_json)
要使
map(&:as_json)
工作,您需要覆盖用户模型中的as_json
方法,并包括一个计算交互计数的方法。例如:def as_json(_opts={})
super(_opts.merge({
methods: [ :interactions_count ]
}))
end
def interactions_count
interactions.size
end
这将为您提供一个用户对象数组,包括它们的交互计数。如果您只需要用户ID,可以执行以下操作:
User.includes(:interactions).order('interactions.created_at desc').uniq.page(params[:page]).per(4).pluck(:id)
希望这有帮助!
关于ruby-on-rails - ActiveRecord PSQL按has_many关联+分页的最新created_at排序,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40728538/