如何在Rails中按查询分组添加限制?

我想吸引前10名选民发表评论并添加分组依据?

示例响应:

1 => [1,2,3,4,5,6,7,8,9,10],2 => [1,4]}

它不能超过10个投票者。

  create_table "votes",force: :cascade do |t|
    t.integer  "user_id",limit: 4,null: false
    t.integer  "votable_id",null: false
    t.string   "votable_type",limit: 191,null: false
    t.integer  "weight",limit: 4
  end

  create_table "comments",force: :cascade do |t|
    t.text     "message",limit: 16777215,null: false
    t.string   "type",limit: 255
    t.integer  "commentable_id",limit: 4
    t.string   "commentable_type",limit: 191
    t.integer  "user_id",null: false
  end

这是我的查询,返回所有选民。相反,我需要为每个评论返回前10名投票者。

Vote.where(votable_id: @comments_ids,votable_type: 'Comment').select(:votable_id,:user_id).group_by(&:votable_id)
marish 回答:如何在Rails中按查询分组添加限制?

像这样吗?

Vote.group(:user_id).limit(10)

,

如果数据不是太大,可以这样:

Vote.where(votable_id: @comments_ids,votable_type: 'Comment')
    .select(:votable_id,:user_id)
    .group_by(&:votable_id)
    .transform_values { |v| v.take(10) }
,
table = Vote.arel_table

Vote.where(votable_id: @comments_ids,:user_id)
    .group(:votable_id,:user_id,:id)
    .order('table[:votable_id].count.desc')
    .limit(10)

这应该给您列出前十名的选票。如果集合很大,则将#group_by与香草红宝石一起使用会花费很长时间。使用Arel可以避免在Rails 6.0中进行任何重大更改,而在这些更改中不允许在查询中使用原始sql。我以前会使用.order('COUNT(votable_id) DESC'),但是会引发错误,并且在Rails 6中是不允许的

,

无法想到执行活动记录或SQL的方式。 但是下面是一个纯Ruby解决方案: 对于ruby 2.4及更高版本,可以在group_by哈希结果上使用Hash#transform_values,如下所示(从查询继续):

votes = Vote.where(votable_id: @comments_ids,votable_type: 
'Comment').select(:votable_id,:user_id).group_by(&:votable_id)

top_voters = votes.transform_values do |val|
  voters = val.map(&:user_id)
  freq = voters.reduce(Hash.new(0)) {|h,v| h[v] += 1; h }
  sorted_votes = voters.uniq.sort_by {|elem| -freq[elem] }
  sorted_votes.take(10)
end
本文链接:https://www.f2er.com/3154691.html

大家都在问