Ruby on rails 最新创建的ActiveRecord PSQL排序有很多关联+;标页码

Ruby on rails 最新创建的ActiveRecord PSQL排序有很多关联+;标页码,ruby-on-rails,postgresql,activerecord,pagination,kaminari,Ruby On Rails,Postgresql,Activerecord,Pagination,Kaminari,从标题开始,我想显示一个用户列表——按最近创建的关联排序 User has_many :interactions 我需要能够显示一个包含用户的表-按用户上次交互日期排序,该表还应显示交互总数(不使用数据库中的计数器缓存),并包括分页 我们使用的上一个(不工作)作用域是沿着User的思路。有许多作用域。包括(:interactions).order(“interactions.created\u at DESC”) 我已经删除了大部分尝试,但我尝试使用MAX(interactions.cre

从标题开始,我想显示一个用户列表——按最近创建的
关联排序

User
  has_many :interactions
我需要能够显示一个包含用户的表-按用户上次
交互
日期排序,该表还应显示交互总数(不使用数据库中的
计数器缓存
),并包括分页

我们使用的上一个(不工作)作用域是沿着
User的思路。有许多作用域。包括(:interactions).order(“interactions.created\u at DESC”)
我已经删除了大部分尝试,但我尝试使用
MAX(interactions.created_at)
并按各种其他属性分组,但没有效果

分页是这里最难的部分-似乎,除非我搞砸了什么,否则使用
:includes
/
左外连接将正确地限制为每个交互只允许一个用户,但是,它似乎被其他交互所限定。我使用的是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
def as_json(_opts={})
  super(_opts.merge({
    methods: [ :interactions_count ]
  }))
end

def interactions_count
  interactions.size
end
给了我们:

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]
它只正确地包含每个用户一次,然而,它包含页面上的用户,而这些用户已经包含在以前的页面上


非常感谢您的帮助。有一段时间,我们一直在反复尝试解决这个问题,但始终无法让它像预期的那样返回。

假设您需要一个用户对象数组,并且由于您正在为每个用户动态生成交互计数,您可以这样做(以及分页)通过将
映射为所有排序交互的每个唯一用户的_json

User.includes(:interactions).order('interactions.created_at desc').uniq.page(params[:page]).per(4).map(&:as_json)
要使
map(&:as_json)
工作,您需要覆盖用户模型中的
as_json
方法,并包含一个计算交互计数的方法。例如:

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
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)

希望这有帮助

假设您需要一个用户对象数组,并且由于您正在为每个用户动态生成交互计数,您可以通过将
映射为所有排序交互的每个唯一用户的json
来实现这一点(以及分页):

User.includes(:interactions).order('interactions.created_at desc').uniq.page(params[:page]).per(4).map(&:as_json)
要使
map(&:as_json)
工作,您需要覆盖用户模型中的
as_json
方法,并包含一个计算交互计数的方法。例如:

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
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)

希望这有帮助

你能把你的疑问贴出来吗?此外,您是在数据库中存储每个用户的交互计数(例如,使用
计数器\u缓存
),还是仅动态生成它(例如
用户.interactions.size
)?@mmichael-使用这些更改编辑OP。动态计数(尽管如果我们可以让排序顺序正常工作,那么牺牲总计数是值得的)并发布了我使用的基本查询。我试过很多其他的,但都没用,所以我把它们删除了。你能发布你的查询吗?此外,您是在数据库中存储每个用户的交互计数(例如,使用
计数器\u缓存
),还是仅动态生成它(例如
用户.interactions.size
)?@mmichael-使用这些更改编辑OP。动态计数(尽管如果我们可以让排序顺序正常工作,那么牺牲总计数是值得的)并发布了我使用的基本查询。我试过很多其他的,但都没用,所以我把它们删除了。不幸的是,这也没有达到预期效果。
uniq
在页面上造成空白点,重复的内容可能会出现,而不是从后面的页面中填写。因此,如果第1页请求10个,那么只有当这5个人参与了最近10次交互时,它才可能返回5个。不幸的是,这也没有像预期的那样起作用。
uniq
在页面上造成空白点,重复的内容可能会出现,而不是从后面的页面中填写。因此,如果第1页请求10个,那么如果这5个人是最近10次交互的一部分,它可能只返回5个。