I'm new to Rails and I am creating a fairly simple site in Rails that has three models: Section, Category, and Post. A Section and a Category both have many posts, so logically I used Post as a join model, and from most of my testing this seems to work. So, my models are as follows:
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
I've seeded the database with the following:
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)
My main issue I'm having right now is taking advantage of the associations in the Show page of the current Section in ERB. If I have more than one Post, it outputs the first iterator over and over again until it runs out of Posts. Here's my 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 %>
So, in this example, it had two posts. So it printed everything out twice. Here's the resulting HTML:
<h1>Cat1</h1>
<p>Desc1</p>
Post 1
Post 2
<h1>Cat1</h1>
<p>Desc1</p>
Post 1
Post 2
I'm thinking about going into the controller and doing the iterations in a hash table, and the passing the hash to the view to go over. However, I don't feel that this will scale and the more content I have eventually the slower that will become, affecting load times, etc. I also don't feel it's idiomatic as far as Rails goes, and there has to be a cleaner way. Can anyone show me what I'm doing wrong here? Thanks in advance for any suggestions/help :)
Edit 1: The expected HTML output is just
<h1>Cat1</h1>
<p>Desc1</p>
Post 1
Post 2
not the way its repeated twice above. It repeats everything proportional to number of poats for some reason, so if there was a Post 3, it would display everything 3 times. I want everything to display exactly once.
Edit 2: I should probably also mention that in the controller,
@section = Section.all
CodePudding user response:
Add uniq
or distinct
after categories can solve this problem
<% s.categories.uniq.each do |c| %>
<h1><%= c.title %></h1>
<p><%= c.description %></p>
<% c.posts.each do |p| %>
<%= p.title %>
<% end %>
<% end %>
What's the difference?
uniq
is an Array method that removes the repeated record in an array.distinct
is an ActiveRecord method that adds an actualDISTINCT
in the SQL phrase and it will trigger a database query.
You can choose anyone depending on your situation.