5.7. Adding Partials

new.html.erb and edit.html.erb both have the code that generates their forms in common. Rails provides partials in order to reuse code and remove repetition, thereby allowing you to include a partial in other view templates. Partials can be spotted thanks to the underscore prefix on their file name (for example, _person.html.erb).

Go ahead and create an empty _form.html.erb file in appviewsarticles. In this file you'll want to include the common snippet of code between the new and edit forms. As such you could copy in _form.html.erb the following code:

<% form_for(@article) do |f| %>
  <%= f.error_messages %>

  <p>
    <%= f.label :title %><br />
    <%= f.text_field :title %>
  </p>
  <p>
    <%= f.label :body %><br />
    <%= f.text_area :body %>
  </p>
  <p>
    <%= f.label :published %><br />
    <%= f.check_box :published %>

</p>
  <p>
    <%= f.label :published_at %><br />
    <%= f.datetime_select :published_at %>
  </p>
  <p>
    <%= f.submit "Update" %>
  </p>
<% end %>

The only problem with this is the value of the Submit button, which is different in the two forms. One is Create and the other says Update. To solve this you can use a local variable (that is, button_value) instead of a string literal (for example, "Create"). You can also change the instance variable @article into a simple variable that's local to the partial, to improve encapsulation.

Copy the following code into _form.html.erb:

<% form_for(article) do |f| %>
  <%= f.error_messages %>

  <p>
    <%= f.label :title %><br />
    <%= f.text_field :title %>
  </p>
  <p>
    <%= f.label :body %><br />
    <%= f.text_area :body %>
  </p>
  <p>
    <%= f.label :published %><br />
    <%= f.check_box :published %>
  </p>
  <p>
    <%= f.label :published_at %><br />
    <%= f.datetime_select :published_at %>
  </p>
  <p>
    <%= f.submit button_value %>
  </p>
<% end %>

Now you can remove the existing form from new.html.erb and edit.html.erb and include the partial you just defined. Go ahead and change the new.html.erb template to look like this:

<h1>New article</h1>

<%= render :partial => "form", :locals => { :article => @article, :button_value =>
'Create
Article' } %>

<%= link_to 'Back', articles_path %>

Similarly, replace the content of edit.html.erb with this:

<h1>Editing article</h1>

<%= render :partial => "form", :locals => { :article => @article, :button_value =>
'Save Changes' } %>

<%= link_to 'Show', @article %> |
<%= link_to 'Back', articles_path %>

As you can see, the highlighted lines render a partial through the render method. The :locals option allows you to specify the value of local variables inside of a hash. In this case you used it to set the variable button_value to "Create Article" when rendering new.html.erb, and to "Save Changes" when rendering edit.html.erb. That value will be rendered as the value of the button in the partial. You also passed to the partial the @article object, which is assigned to its local variable article.

Using :locals to assign values to variables local to the partial is conceptually similar to passing arguments to a method.

In this way the repetition is eliminated, and any changes to the _form.html.erb partial will be reflected automatically in the templates for the new and edit actions. That's DRY.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.75.221