Partials¶
One of the main principles of the Rails development framework is DRY - "Don't Repeat Yourself." Basically, this means that wherever it is possible, you should reduce the use of duplicate chunks of code.
Your application may have several views that all display the same content in the same format. For example, you may display an author's photo, name, and biography on each of the following pages:
1) The show view for each of the author's books
2) The index view for all of the authors
3) The show view for a publisher, where you display all of the authors in that publisher's stable
4) A spotlighted or featured author section on the home page of the site
That is a lot of places to have to maintain essentially the same content. If you decide to hyperlink the author's name to his/her email address, for instance, you'd have to do it four times, and just hope you didn't forget one.
A better approach would be to pull the author's information into a file of its own, known as a partial. You can render a partial into another view using the following code snippet:
<%= render :partial => 'directory_path/name_of_partial' %>
Partials are named with a preceding underscore character (_), so if you had a partial that displayed an author's info, you would name it _author.html.erb. Then to render the partial into another view, you would input into your view this code:
<%= render :partial => 'shared/author' %>
This assumes that you had saved the partial in the app/views/shared directory. This is a good place to store partials that you expect to use in the context of several models' views. If you save the partial into the same directory as the view that is calling it, you can shorten the partial call to this:
<%= render :partial => 'author' %>
Often, you will need to reference variables inside the partial itself. In that case, you need to pass a reference to the variable from the view that is calling it. You do so using the locals parameter. If your view is displaying the details of a
@bookobject and you want to be able to refer to the book's author in your partial, you would modify the call to your partial like this:
<%= render :partial => 'shared/author', :locals => {:author => @book.author} %>
Sometimes you may need to print items within an array. For example, if you wanted to show a table with a list of authors instead of using
@authors.each |author|you could call a partial for each element of the array like this.
<%= render :partial => 'shared/author_record', :collection => @authors %>
In this partial you may have something like
<tr>
<td>
<%= author_record.name %>
</td>
</tr>
Notice that the name of the partial is used to represent the specific element of the array being passed into the partial. Another handy variable passed into the partial is a counter which specifies how many times the partial has been called. So if we wanted to print an author number next to each name we could do this.
<tr>
<td>
<%= author_record_counter %>
</td>
<td>
<%= author_record.name %>
</td>
</tr>
You will find the use of partials especially helpful when you try to "DRY up" (reduce replication) your edit and new views. For most models, these forms - or huge parts of them, at least - are virtually identical. Pulling the duplicate code out and placing it into partials is a perfect way to reduce the number of lines of code and increase the code's maintainability, without sacrificing functionality.
