从标题开始,我想显示一个用户列表 - 按最近创建的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]
它恰好只包含每个用户一次,但是,当用户已经包含在以前的页面中时,它会包括用户。
非常感谢任何帮助。一直在回到这个问题,然后尝试解决它一段时间,并且永远无法按预期返回。
答案 0 :(得分:0)
假设您需要一组用户对象,并且由于您为每个用户动态生成交互计数,您可以通过为所有用户的每个唯一用户映射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)
希望这有帮助!