Rails gives you a lot of functionality for free if you know how to name things and where to place them in the file tree.
For example, look at the following stages of refactoring a list of child elements to the parent element, in the #show page.
class Article < ActiveRecord::Base
has_many :comments
has_many :people, through: :comments
end
class Comment < ActiveRecord::Base
belongs_to :article
belongs_to :person
delegates :commenter, to: :person
end
class Person < ActiveRecord::Base
has_many :comments
alias_attribute :commenter, :full_name
def full_name
[first_name, last_name].join(' ')
end
end
class ArticlesController < ApplicationController
def show
@article = Article.includes(:people, :comments).find(params[:id])
end
...
end
<!-- views/articles/show.html.erb -->
...
<h2>Comments:</h2>
<%- for comment in @article.comments do ->
<h3><%= comment.commenter %></h3>
<%= simple_format comment.body %>
<%- end %>
Get the join out of the view
class ArticlesController < ApplicationController
def show
@article = Article.find(params[:id])
@comments = @article.includes(:people).comments
end
...
end
<!-- views/articles/show.html.erb -->
...
<h2>Comments:</h2>
<%- for comment in @comments do ->
<h3><%= comment.commenter %></h3>
<%= simple_format comment.body %>
<%- end %>
Make a partial for the comments
<!-- views/comments/_comment.html.erb -->
<h3 class="comment-author"><%= comment.commenter %></h3>
<%= simple_format comment.body %>
Now you can do this in your articles view
<!-- views/articles/show.html.erb -->
...
<h2>Comments:</h2>
<%= render @comments %>
Not only is this easier to read, it also means you can render a comment or comments elsewhere
class PeopleController < ApplicationController
...
def show
...
@recent_comments = @person.comments.order(:id).reverse.limit 5
...
end
...
end
/* assets/stylesheets/people.css */
.recent-comments .comment-author {
display: none;
}
<!-- views/people/show.html.erb -->
...
<aside class="recent-comments">
<h2>What I’ve said lately:</h2>
<%= render partial: 'comments/comment', collection: @recent_comments %>
</aside>
No additional work needed, besides collecting the list of comments. Rails knows how to render them because the partial is in the correct views folder and is named for the model. You can override any and all of these conventions, but if you follow the conventions, you don’t have to remember all the arguments needed to do so.