【问题标题】:How do a search a table for similar records and displaying count - Ruby on Rails如何在表中搜索相似记录并显示计数 - Ruby on Rails
【发布时间】:2011-02-07 18:20:11
【问题描述】:

我在我正在构建的 Ruby on Rails 应用程序中创建了一个名为标签的表。它是一个博客应用程序,因此我允许用户将标签与帖子相关联,并通过 :posts、:has_many => 标签和 Tag belongs_to :post 关联来做到这一点。

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

例如,如果 tag_name Sports 的 Tag 表中有 10 个条目。如何在视图中显示 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

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    执行以下操作:

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

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

    要显示与标签名称相关的帖子,请执行以下操作:

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

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

    【讨论】:

    • 这可能是个愚蠢的问题,但看起来这是我将在标签控制器中用于定义计数的代码。如果是这种情况,我如何在视图中渲染? ?
    • 伙计,非常感谢您抽出宝贵的时间来做这件事。我明天第一件事会检查它。再次,我真的很感激。
    • 嘿,伙计,我想越来越近了。当您使用@tag_counts = Tag.count(:group => :name) 设置计数哈希时,您说要放入控制器。我已经在应用程序控制器以及帖子和标签中尝试过,但都没有工作。你能告诉我更多关于把它放在哪里以及如何放置的细节吗(比如我做一个 def tag_count blah end 吗?
    • 你说你要在/views/posts/index.html.erb中使用这个,所以你必须把@tag_counts = Tag.count(:group =&gt; :name)放在indexindex方法中PostsController
    • 在控制器动作中设置@tag_counts,与显示标签名称的视图关联。
    【解决方案2】:

    首先——你的联想似乎有误。标签和帖子是多对多关联,而不是一对多。

    我强烈建议您查看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
    

    但是,同样,使用预先构建的解决方案会容易得多。

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

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

    <%= 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)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多