简体   繁体   中英

Rails Way of Grouping By an Association

I know I am making this more difficult than it needs to be. There has to be a rails way of accomplishing this task. To demonstrate: here are two models:

#app/models/user.rb
class User < ActiveRecord::Base
  has_many :blogs

  def to_s
    name
  end
end

#app/models/blog.rb
class Blog < ActiveRecord::Base
  belongs_to :user
    delegate :name, to: :user, prefix: true, allow_nil: true

  def to_s
    title
  end
end

So what I want to do is group all of the blogs by the associated user . Then I want to list those blogs per each user .

Key Detail : not all blogs have an associated user . Some have user_id = nil . Here is a listing of the blogs to demonstrate (last two blogs have user_id = nil ):

列出博客

So I got what I wanted to work. But the solution is not easy to read, and I know there must be some way to accomplish this using Rails' query interface . I couldn't figure it out though, so I hacked together my own solution below:

#app/controllers/admin_controller.rb
class AdminController < ApplicationController
  def index
    @group_blogs_by_user = {}
    User.all.pluck(:name).each{|user| @group_blogs_by_user[user] = []}
    @group_blogs_by_user[nil] = [] #provide nil category when no user_id was specified for a blog

    Blog.all.each {|blog| @group_blogs_by_user[blog.user_name].push(blog)}

    @group_blogs_by_user.reject!{ |_ , v|v.empty?} #do not show users that have no blogs
  end
end

And here is the view to display it:

#app/views/admin/index.html.erb
<h1>Showing Count of Blogs per User</h1>
<table>
  <thead>
    <th>User</th>
    <th>Blogs Count</th>
  </thead>
  <tbody>
        <% @group_blogs_by_user.each do |user, blogs_of_this_user| %>      
        <tr>
      <td><%= user || "No User Specified"%></td>
      <td><%= blogs_of_this_user.size %></td>
    </tr>
  <% end %>
  </tbody>
</table>

<hr>

<h1>Showing Breakdown of Blogs per User</h1>
<% @group_blogs_by_user.each do |user, blogs_of_this_user| %>
  <h3><%= (user || "No User Specified") + " (#{blogs_of_this_user.size} blogs)" %></h3>
  <table class="table">
    <thead>
        <th>Blog ID</th>
        <th>Created At</th>
    </thead>
    <tbody>
    <% blogs_of_this_user.each do |blog| %>
      <tr>
        <td> <%= link_to(blog.id, blog)%></td>
        <td> <%= blog.created_at.strftime("%d-%m-%Y")%></td>
      </tr>
    <% end %>
    </tbody>
  </table>
<% end %>

And here is what it renders, which is what I want:

按用户分组的博客

I run into this situation all the time where I want to group a table by some association, and I find myself continually hacking together a solution. How can I do this the rails way with Rails' Query Interface?

To get all the blogs from a user and print the username, blog_id and blog count

<% @users.each do |user| %>
    <%= user.name %>
    <%= user.blogs.count %>
    <% user.blogs.each do |blog|%>
        <%= blog.id %>
    <% end %>
<% end %>

To get the amount of blogs with no user

<%= Blog.where(user: nil).count %>

I hope I got your question right and this helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM