我将以下类别组合在一起
@categories = Category.all.group_by { |c| c.name }
在我看来,我正在显示类别名称
<% @categories.each do |c, v| %>
<li><%= link_to c, blog_path(:name => c) %></li>
<% end %>
例如
Ruby
Ruby On Rails
CSS
我希望实现的是每个类别名称旁边都有该类别名称的帖子总数,所以
Ruby(2)
Ruby On Rails(10)
所以我试过了
@categories = Category.joins(:posts).all.group_by { |c| c.name }
这导致仅显示带有帖子对象的类别(以前所有类别都会显示,无论他们是否有帖子对象),在我的视图中我试过
<% @categories.each do |c, v| %>
<li><%= link_to c, blog_path(:name => c) %><%= c.count %></li>
<% end %>
哪个没有输出。我以为在问题混淆之前我会问如何解决这个问题,如果有人能够解释答案以及我会非常感激
非常感谢
答案 0 :(得分:5)
调用分组类别@categories令人困惑,因为这使得它听起来像是Category对象的集合,当它实际上是一个哈希时。使用描述性名称(包括在循环中)可以使代码更清晰。
试试这个:
@category_groups = Category.includes(:posts).all.group_by { |c| c.name }
和视图
<% @category_groups.each do |name, categories| %>
<li><%= link_to name, blog_path(:name => name) %> (<%= categories.map{|category| category.posts.size}.sum %> posts)</li>
<% end %>
答案 1 :(得分:1)
我不确定你为什么要使用group_by
。但是,由于您在posts
上没有任何条件,因此您不需要加入。其他示例建议热切加载帖子,但是初始化内存中的所有post对象以获得它们的计数似乎有些过分。你需要做自己的基准测试。考虑一个像另一个回答者建议的counter_cache。
@categories = Category.all
并在视图中:
<% @categories.each do |c| %>
<li><%= link_to c.name, blog_path(:name => c.name) %> (<%= c.posts.count %> posts)</li>
<% end %>
进一步说明
group_by
返回一个带有键的哈希值作为块中的唯一返回值,该值是块计算到该键的原始数组的所有项。以Category.all
为例(范围在group_by
之前转换为数组,以便我们在此处表示它们):
cats = [
#<Category name: "foo" ... >,
#<Category name: "bar" ... >,
#<Category name: "baz" ... >
]
这三个类别具有唯一的名称,因此使用.group_by { |c| c.name }
除了创建一个以键为名称的无意义哈希,并且每个值都作为一个具有一个Category对象的数组之外什么都不做:
{
"foo" => [#<Category name: "foo" ... >],
"bar" => [#<Category name: "bar" ... >],
"baz" => [#<Category name: "baz" ... >]
}
以下是您可以使用group_by
实现某些效果的示例:
languages = ["Ada", "C++", "CLU", "Eiffel", "Lua", "Lisp",
"Perl", "Python", "Smalltalk"]
languages_grouped_by_first_letter = languages.group_by { |s| s[0] }
=> {"A"=>["Ada"], "C"=>["C++", "CLU"], "E"=>["Eiffel"], "L"=>["Lua", "Lisp"], "P"=>["Perl", "Python"], "S"=>["Smalltalk"]}
答案 2 :(得分:0)
使用以下代码
@categories = Category.all.group_by { |c| c.name }
编写Hepler以查找post_count
def post_count(category_ids)
Post.where(:category_id => category_ids)
end
在视图中:
<% @categories.each do |c, v| %>
<li><%= link_to c, blog_path(:name => c) %>(<%= post_count(v.map(&:id)) %>)</li>
<% end %>
希望这有帮助! :)
答案 3 :(得分:0)
您要找的是counter_cache
。
在我们的Post
模型中,设置counter_cahe => true
class Post < ActiveRecord::Base
belongs_to category,:counter_cache => true
end
将posts_count
列添加到categories
表并执行此操作
@category_groups = Category.find(:all)
<% @category_groups.each do |c| %>
<li><%= link_to name, blog_path(:name => c) %>(<%= posts_count)</li>
<% end %>
查看 Railscast 以实现此目的。