Rails follows and encourages the DRY principle–Don’t Repeat Yourself. This principle states that everything should be in the system once; you don’t duplicate anything.
One particular area of much duplication in web applications are the forms for creating a new object and editing the object–often, they have the same fields, the same layout, and they manage the same data in a very similar way; is there a way to combine them into one file, so that you share the form?
The answer is yes; Rails provides an easy way to do this.
Conceptually, what you want to do is share the edit form–put data, if there is any (because it’s an edit), into the right fields. The new form is almost a copy–the only difference being it creates a new object, rather then updating an existing object. The only catch is making sure the form submits the data to the right actions.
The first step is to set up your edit form properly using the form helpers. You can find a sample below–an article form for a blog–which demonstrates a few of the types of input fields.
<% form_for(@article) do |f| %>
Title: <%= f.text_field :title %>
<%= f.text_area :content, :cols => 60 %>
Published? <%= f.check_box :is_published %>
<%= f.hidden_field :user_id %>
<%= f.submit "Go!" %>
<% end %>
form_for(variable) line sets up the
form tag, and specifies the variable the form is for–Rails uses this to match the values you put in later to form attributes.
As you can see, Rails provides helpers for text fields (input tag), text areas (textarea tag), hidden fields, and buttons. These helpers make coding easier, but also make it a snap for us to create a reusable, sharable form for our new and edit forms.
You can save your form as edit.html.erb and look at it. The next step is to share the form; Rails allows this via partials.
Partials are Rails’ solution to sharing view “code” or HTML. You can separate chunks of your website’s views–such as the header, footer, navigation bar, shopping cart, and so on–into reusable partial files, and render them from any view page.
To “render” a partial in a view, simply add the following code:
render :partial => "filename"
Rails then looks for a file called
_filename.html.erb (or _filename.rhtml) in your current controller’s view directory, and renders that. If you want to render a partial from another controller, you can specify
render :partial => "controller/filename".
How do we use this? Simply save your form as _form.html.erb, and call
render :partial => "form" from your edit and new view pages.
And that’s it! Because you use the form helpers, rails fills in the relevant details, and your form works for new AND edit! Rails even changes the target of the form to point to the right place–whether to edit or to create an object! You can add different titles, different content, etc. around the forms to each of the new and edit view pages as necessary, while sharing the form. It’s amazing how easy Rails makes it to create complex, robust apps without complex code!