如何在不产生重复的情况下遍历 ERB 中的 has_many :through 关联?

How do I iterate through a has_many :through association in ERB without producing duplicates?

我是 Rails 的新手,我正在 Rails 中创建一个相当简单的站点,它具有三个模型:部分、类别和 Post。一个部分和一个类别都有很多帖子,所以逻辑上我使用 Post 作为连接模型,并且从我的大部分测试来看这似乎有效。所以,我的模型如下:

class Category < ApplicationRecord
   has_many :posts
   has_many :sections, through: :posts
end

class Post < ApplicationRecord
   belongs_to :section
   belongs_to :category
end

class Section < ApplicationRecord
   has_many :posts
   has_many :categories, through: :posts
   
   has_rich_text :description

   def to_param
      url
   end
end

我在数据库中添加了以下内容:

general = Section.create(title: "General", description: "Description of the General section", url: "general")
c1 = Category.create(title: "Cat1", description: "Desc1")
p1 = Post.create(title: "Post 1", blurb: "Blurb 1", body: "Body 1", section: general, category: c1)
p2 = Post.create(title: "Post 2", blurb: "Blurb 2", body: "Body 2", section: general, category: c1)

我现在遇到的主要问题是利用 ERB 当前部分的显示页面中的关联。如果我有多个 Post,它会一遍又一遍地输出第一个迭代器,直到用完 Post。这是我的 ERB:

<% @section.each do |s| %>
  <% if request.path == section_path(s) %>
    <% s.categories.each do |c| %>
      <h1><%= c.title %></h1>
      <p><%= c.description %></p>
      <% c.posts.each do |p| %>
        <%= p.title %>
      <% end %>
    <% end %>
  <% end %>
<% end %>

所以,在这个例子中,它有两个帖子。所以它把所有的东西都打印了两次。这是结果 HTML:

      <h1>Cat1</h1>
      <p>Desc1</p>
        Post 1
        Post 2
      <h1>Cat1</h1>
      <p>Desc1</p>
        Post 1
        Post 2

我正在考虑进入控制器并在散列中进行迭代 table,然后将散列传递给视图以进行检查。但是,我不认为这会扩展,而且我最终拥有的内容越多,速度就越慢,影响加载时间等。就 Rails 而言,我也不觉得它是惯用的,并且那里必须是一种更清洁的方式。谁能告诉我我在这里做错了什么?提前感谢任何 suggestions/help :)

编辑 1:预期的 HTML 输出只是

     <h1>Cat1</h1>
      <p>Desc1</p>
        Post 1
        Post 2

不是上面重复两次的方式。由于某种原因,它会重复与 poats 数量成比例的所有内容,因此如果有 Post 3,它将显示所有内容 3 次。我希望所有内容只显示一次。

编辑 2:我可能还应该提到在控制器中, @section = Section.all

分类后添加uniqdistinct即可解决此问题

<% s.categories.uniq.each do |c| %>
  <h1><%= c.title %></h1>
  <p><%= c.description %></p>
  <% c.posts.each do |p| %>
    <%= p.title %>
  <% end %>
<% end %>

有什么区别?

  • uniq是一个数组方法,删除数组中的重复记录。
  • distinct是一个ActiveRecord方法,在SQL短语中添加一个实际的DISTINCT,它会触发数据库查询。

您可以根据自己的情况选择任何人。