如何在Rails中正确使用group/group_by适配Chartkick展示好友完成任务数据
问题:按user_id分组好友完成任务后柱状图无数据展示
我需要展示用户好友完成的任务,现有返回布尔值的friend?函数。生成柱状图的代码如下:
<%= bar_chart @completed_tasks.count%>
目前获取目标数据的方式:
@completed_tasks = Task.where(completed: true).select{|task| friend?(task.user_id)}
现在要按user_id分组,但尝试以下三种方式后柱状图无数据展示,求错误原因:
.group(:user_id).group_by(:user_id).group_by(&:user_id)
错误原因分析
.group(:user_id)无效:这是ActiveRecord的数据库层面分组方法,但你先用Ruby数组的select方法把数据库查询结果转成了内存中的数组,数组没有.group方法,调用后要么报错,要么返回无效数据。.group_by(:user_id)写法错误:Ruby数组的group_by不支持直接传:user_id符号作为参数,这种写法会把符号本身当成分组键,导致分组结果完全不符合预期,统计出来的数量自然无法被柱状图识别。.group_by(&:user_id)统计方式错误:这个写法能正确把任务按user_id分组,返回{user_id => [任务实例列表]}的哈希结构,但你直接调用.count会返回哈希的键值对总数,而不是每个用户的任务完成数,柱状图无法解析这种数据结构。
正确解决方法
方法一:数据库层面筛选+分组(推荐,效率更高)
先通过friend?逻辑获取所有好友的ID列表,直接在数据库层面完成筛选和分组统计:
# 先获取所有好友的ID(根据你的friend?逻辑调整获取方式) friend_ids = User.all.select { |user| friend?(user.id) }.pluck(:id) # 数据库层面筛选好友的已完成任务,分组统计每个用户的任务数 @completed_tasks = Task.where(completed: true, user_id: friend_ids) .group(:user_id) .count
视图中直接传入统计结果:
<%= bar_chart @completed_tasks %>
方法二:内存中筛选后再统计(适合friend?逻辑无法转成SQL的场景)
如果friend?逻辑复杂,无法转成数据库查询,就在内存中筛选后再统计每个用户的任务数:
@completed_tasks = Task.where(completed: true) .select { |task| friend?(task.user_id) } .group_by(&:user_id) .transform_values(&:count)
视图中同样直接传入:
<%= bar_chart @completed_tasks %>
内容的提问来源于stack exchange,提问作者Liuba
相关产品推荐
相关产品推荐

