我在我正在构建的Ruby on Rails应用程序中创建了一个名为Tags的表。它是一个博客应用程序,因此我允许用户将标签与帖子关联,并通过以下方式执行此操作:posts,:has_many =>标签和标签belongs_to:发布关联。
现在我有了我的标签表,我试图看看如何渲染视图,以便显示标签和标签计数。 (应该注意的是,我试图在/views/posts/index.html.erb文件中呈现这一点。)
例如,如果Tag表中有10个条目用于tag_name Sports。如何在视图中显示Sports(10)。我不打算为特定标签执行此操作,而是以某种方式搜索表格,组合标签并显示所有标签的列表以及旁边的计数。 (我真的希望这些链接指向包含该标记的帖子列表,但我很早就学会了只提出一个问题)。
希望这是有道理的。
评论更新
视图
<% @tag_counts.each do |tag_name, tag_count| %>
<tr>
<td><%= link_to(tag_name, posts_path(:tag_name => tag_name)) %> </td>
<td>(<%=tag_count%>)</td>
</tr>
<% end %>
postsController:
def index
@tag_counts = Tag.count(:group => :tag_name)
@posts = Post.all :order => "created_at DESC"
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @posts }
format.json { render :json => @posts }
format.atom
end
end
答案 0 :(得分:4)
执行以下操作:
Tag.count(:group => :name).each do |tag_name, tag_count|
puts "tag_name=#{tag_name}, tag_count=#{tag_count}"
end
如果在name
表的tags
列上添加索引,则可以提高性能。
要显示与标记名称关联的帖子,请执行以下操作:
在控制器方法中设置计数哈希:
在与显示标记名称的视图关联的控制器操作中设置@tag_counts
。
@tag_counts = Tag.count(:group => :tag_name)
在视图中将每个标记显示为链接:
<% @tag_counts.each do |tag_name, tag_count| %>
<%= link_to(tag_name, posts_path(:tag_name => tag_name)) %> (<%=tag_count%>)
<% end %>
该链接指向PostsController
的索引方法。每个链接都有一个tag_name
参数。
index
方法PostsController
:
class PostsController < ApplicationController
def index
@tag_counts = Tag.count(:group => :tag_name)
conditions, joins = {}, nil
unless (params[:tag_name] || "").empty?
conditions = ["tags.tag_name = ? ", params[:tag_name]]
joins = :tags
end
@posts=Post.all(:joins => joins, :conditions => conditions)
end
end
修改强>
更新了代码,将name
字段更改为tag_name
。
答案 1 :(得分:0)
首先 - 您的关联似乎有误。标签和帖子是多对多关联,而不是一对多。
我强烈建议您查看其中一个acts_as_taggable实现为您执行此操作。否则,如果您愿意,您可以创建一个has_many :through
关联,但这将重新发明轮子。
对于每个页面加载,在集合上调用count()
是非常糟糕的主意,因为这会让您在每个标记的数据库中点击;大规模的非常昂贵的操作。此外,具有给定标记的帖子数量不是您需要在请求时计算的数字,因此这种方法既昂贵又不必要。
Rails有一个名为counter_cache
的内置功能,可以通过在整数字段中缓存相关记录的数量并在创建新记录时更新它来为您处理这个问题。以下是您设置的方式:
为tags
表格创建迁移:
def up
add_column :tags, :taggings_count, :integer, :default => 0
Tag.reset_column_information
Tag.all.each do |t|
Tag.update_counters t.id, :taggings_count => t.taggings.length
end
end
def down
remove_column :tags, :taggings_count
end
并更改belongs_to
关联:
class Tagging < ActionRecord::Base
belongs_to :tag, :counter_cache => true
belongs_to :post
end
如果您正在构建自己的标记系统,则可以连接其余两个模型,如下所示:
class Post < ActiveRecord::Base
has_many :taggings
has_many :tags, :through => :taggings
end
class Tag < ActiveRecord::Base
has_many :taggings
has_many :posts, :through => :taggings
end
但是,再一次,使用预先构建的解决方案要容易得多。
从现在开始,每次通过Post
模型与Tag
创建新的Tagging
关联时,它都会自动为您更新taggings_count
列。< / p>
在您的视图中,您可以像任何其他列一样在迭代时显示计数:
<%= link_to "#{tag.name} (#{tag.taggings_count})", posts_path(:tag_name => tag.name) %>
进一步阅读:
ActiveRecord has_many :through associations
ActiveRecord association basics (:counter_cache discussed in section 4.1.2.4)