【问题标题】:How to count a has_many relationship using active record?如何使用活动记录计算 has_many 关系?
【发布时间】:2018-09-02 16:45:10
【问题描述】:

我有一个连接表,其中列出了 user_iditem_id(多对多关系)。

我试图在 erb 页面上显示用户拥有多少项目。

我该怎么做?

我的联接表/模型 UserItem 现在有 11 条记录,所以很明显,如果我这样做 UserItem.count,它会给我 11 条记录。

但是我如何告诉它对于每个 user_id,计算该特定用户有多少 item_id?然后显然我会迭代这个。

编辑:

好的,我发现 UserItem.group(:user_id).distinct.count 给了我 {user_id => # of items per user} 的哈希值。

我如何不仅迭代哈希,而且使它与每个当前 user_id 相关联?

<% @users.each do |user| %>
          <li><%= user.username %>
          has been to <%= UserItem.group(:user_id).distinct.count %>!</li>
        <% end %>

到目前为止,这只是插入哈希,我如何对应每个 user_id 使其与显示的 user.username 对齐?

【问题讨论】:

  • UserItem.where(user_id: :id).count 我想。
  • 这是有道理的,但是返回 0。还有其他想法吗?
  • 对于 SQL 问题,请添加表定义、示例数据、所需输出以及您尝试过的内容。
  • 我在原始帖子中添加了一个编辑!

标签: sql ruby activerecord sinatra-activerecord


【解决方案1】:

我假设您在 UserItemUserItem 之间有一个 has_many :through 关联,并且您需要在具有相关项目计数的所有用户的视图中显示该列表。

这是一种选择。

在控制器中(按 item_count 排序):

@users = User.joins(:user_items).group('user_items.user_id').select('users.*, COUNT(*) as item_count').order('item_count DESC')

在视图中(非常基本):

<% @users.each do |user| %>
  <p><%= user.name %> | <%= user.item_count %></p>
<% end %>

在我的评论中有一个语法错误,用于计算@user 的项目,如果id = @user.id

UserItem.where(user_id: id).count

**Edit1:** 也显示没有项目的用户。

选项一,在上面的代码中添加以下内容,以获取没有项目的用户:

@users_without_items = User.includes(:items).where(items: {id: nil})

<% @users_without_items.each do |user| %>
  <p><%= user.name %> | 0</p>
<% end %>

或一次全部获取(未排序,触发大量查询):

@user = User.all

<% @user.each do |user| %>
  <p><%= user %> | <%= user.categories.count %></p>
<% end %>

**Edit2:** 获取“{user_id => # of items per user}”的哈希值

一个选项可以列出所有用户并通过它的键从哈希中获取计数:

@user_items_count = UserItem.group(:user_id).count
@users = User.all

<% @users.each do |user| %>
  <p><%= user.name %> | <%= @user_items_count[user.id] || 0 %></p>
<% end %>

**在使用 `ActiveRecord` 和 `erb` 的 `Rails` 中测试。**

【讨论】:

  • @Caliz 我添加了一个编辑。使用UserItem.group(:user_id).distinct.count,您将获得纯整数而不是活动记录对象。您可以在我的编辑中使用它,也可以映射哈希以将键转换为对象:@user_items_count.map { |k,v| [User.find(k), v]}.to_h,然后对其进行迭代(它会触发大量查询)。
  • @iGian 非常感谢!
  • @Caliz 如果它回答了您的问题,请将其标记为答案
猜你喜欢
  • 1970-01-01
  • 2013-07-27
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多