Calling partials through helpers
April 3rd, 2008
Rails partials are are fragments of template code that can be inserted into a view. They can really simplify template code, by factoring out repeated code.
For example, I often put forms into a partial so that the form can be shared be create and edit views:
= error_messages_for :quiz
- form_for :quiz, @quiz, :url => quizzes_path, :html => {:method => :post} do |form|
= render :partial => 'quizzes/form', :locals => {:form => form}
= submit_tag 'Create'
= error_messages_for :quiz
- form_for :quiz, @quiz, :url => quiz_path(@quiz), :html => {:method => :put} do |form|
= render :partial => 'quizzes/form', :locals => {:form => form}
= submit_tag 'Update'
Many (most) people put the render call directly in their templates. This is not a good idea! What if you want to change the template path, or conditionally render a different template in certain conditions? Now you've got to repeat yourself in both templates, and that's bad news.
A simple way to fix this is to *always* use a helper to render the partial. That way any changes can be made in one place, and it also a great place to store any messy conditional logic so that it doesn't clutter up your templates.
= error_messages_for :quiz
- form_for :quiz, @quiz, :url => quizzes_path, :html => {:method => :post} do |form|
= quiz_form(form)
= submit_tag 'Create'
= error_messages_for :quiz
- form_for :quiz, @quiz, :url => quiz_path(@quiz), :html => {:method => :put} do |form|
= quiz_form(form)
= submit_tag 'Update
def quiz_form(form)
render :partial => 'quizzes/form', :locals => {:form => form}
end
Now if I want to do something, like say render a different form depending on a user's preference, it's easy to do.
= error_messages_for :quiz
- form_for :quiz, @quiz, :url => quizzes_path, :html => {:method => :post} do |form|
= quiz_form(form, current_user)
= submit_tag 'Create'
def quiz_form(form, user = nil)
if(!user.nil? && user.wants_advanced_quizzes))
render :partial => 'quizzes/advanced_form', :locals => {:form => form}
else
render :partial => 'quizzes/form', :locals => {:form => form}
end
end



Sorry, comments are closed for this article.