2016-11-21 53 views
1

从标题开始,我想显示一个用户列表 - 按最近创建的has_many关联进行排序。ActiveRecord PSQL根据has_many association +分页的最近created_at排序

User 
    has_many :interactions 

我需要能够显示与他们的最后interaction日期排序的用户 - 一个表,这个表应该(在DB没有使用counter_cache)显示交互的总数,以及,还包括分页。

,我们一直在使用以前的(不工作)范围是沿User.with_a_bunch_of_scopes.includes(:interactions).order("interactions.created_at DESC") 我已经删除了大部分的尝试的台词,但我已经使用MAX(interactions.created_at)和分组的各种其他属性试过,但无济于事。

分页是最困难的部分这里 - 看来,除非我搞乱了的东西,即使用:includes/LEFT OUTER JOIN适当限制每次互动只有一个用户,然而,似乎是由其他交互作用域。我使用的是雷宝石,但我能够使用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] 

它恰当地只包括​​每个用户一次,但是,我当他们已经被包括在前面的页面中时,包括页面上的用户。

任何帮助,非常感谢。我们不时回到现在,然后尝试解决它一段时间,并且永远无法按预期返回。

+0

能否请您发布您的查询?另外,您是否将每个用户的交互次数存储在数据库中(例如,使用'counter_cache')或者只是动态生成它(例如'user.interactions.size')? – mmichael

+0

@mmichael - 用这些更改编辑OP。动态计数(尽管值得牺牲总数,如果我们可以得到排序顺序)并发布我正在使用的基本查询。我已经尝试了很多其他人,但没有任何工作,所以我删除了他们。 – Rockster160

回答

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) 

希望这会有所帮助!

+0

不幸的是,这并不像预期的那样工作。'uniq'在页面上出现空白点,而重复页面可能存在,而不是从后续页面填充。因此,如果第1页请求10,那么如果这5个人已经参与了最近10次交互,那么它可能只返回5。 – Rockster160