从标题开始,我想显示一个用户列表-按最近创建的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,但是能够使用limitoffset复制问题
例如:
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/

10-17 00:44