如何在不产生重复的情况下遍历 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
分类后添加uniq
或distinct
即可解决此问题
<% 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
,它会触发数据库查询。
您可以根据自己的情况选择任何人。
我是 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
分类后添加uniq
或distinct
即可解决此问题
<% 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
,它会触发数据库查询。
您可以根据自己的情况选择任何人。