如何在表中搜索类似记录并显示计数 – Ruby on Rails

我在我正在构建的Ruby on Rails应用程序中创建了一个名为Tags的表。 它是一个博客应用程序,所以我允许用户将标签与post关联,并通过:posts,:has_many =>标签和标签belongs_to:post association进行。

现在我有了我的标签表,我试图看看如何渲染视图,使其显示标签和标签计数。 (应该注意的是,我试图在/views/posts/index.html.erb文件中渲染它)。

例如,如果Tag表中有10个条目用于tag_name Sports。 如何在视图中显示运动(10)。 我不打算为特定标签执行此操作,而是以某种方式搜索表格,组合标签并显示所有标签的列表以及旁边的计数。 (我真的希望这些链接指向包含该标签的post列表,但我很早就学会了一次只问一个问题)。

希望有道理。

更新评论

视图

   tag_name)) %>  ()   

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 

请执行下列操作:

 Tag.count(:group => :name).each do |tag_name, tag_count| puts "tag_name=#{tag_name}, tag_count=#{tag_count}" end 

如果在tags表中的name列上添加索引,则可以提高性能。

要显示与标记名称关联的post,请执行以下操作:

在控制器方法中设置计数哈希:

在与显示标记名称的视图关联的控制器操作中设置@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参数。

PostsControllerindex方法中:

 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

首先 – 你似乎错了你的关联。 标签和post是多对多关联,而不是一对多关联。

我强烈建议您查看其中一个acts_as_taggable实现来为您执行此操作。 否则你可以根据需要创建一个has_many :through关联,但这将重新发明轮子。

对于每个页面加载,在集合上调用count()是一个非常糟糕的主意 ,因为这会使您为每个标记命中数据库; 大规模的非常昂贵的操作。 此外,具有给定标记的post数量不是您需要在请求时计算的数字,因此这种方法既昂贵又不必要。

Rails有一个名为counter_cache的内置function,可以通过在整数字段中缓存相关记录的数量并在创建新记录时更新它来为您处理这个问题。 这是你如何设置它:

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 

但是,再次使用预先构建的解决方案要容易得多。

从现在开始,每次通过Tagging模型为Tagging创建新的Post关联时,它都会自动为您更新taggings_count列。

在您的视图中,您可以像任何其他列一样在迭代时显示计数:

 <%= link_to "#{tag.name} (#{tag.taggings_count})", posts_path(:tag_name => tag.name) %> 

进一步阅读:
ActiveRecord has_many:通过关联
ActiveRecord关联基础知识(:第4.1.2.4节讨论的counter_cache)