Wednesday, 12 February 2014

Polymorphic Path

Polymorphic path

Every now and then you might end up with something like the following route structure:
resources :projects do
  resources :tasks do
    resources :documents
  end
  resources :users do
    resources :documents
  end
end
which inevitably leads to views like this:
- if @task
    = link_to 'Document' project_task_document_path(@project, @task, @document)
- else
    = link_to 'Document', project_user_document_path(@project, @user, @document)
It's pretty frustrating when you're trying to achieve logicless view nirvana.
Enter polymorphic_path. This little bit of Rails voodoo allows you to achieve the following with the above example:
= link_to 'Document', polymorphic_path(@project, @task || @user, @document)
But what if you want to do the same but with an edit action?
No problem:
= link_to 'Edit Document', edit_polymorphic_path(@project, @task || @user, @document)
New and index actions get a little trickier but are still extremely simple
= link_to 'New Document', new_polymorphic_path(@project, @task || @user, :document)
= link_to 'Documents', polymorphic_path(@project, @task || @user, :documents)
polymorphic_path builds on the work in polymorphic_url which is just another component of the Rails framework. Methods such as form_for, url_for and redirect_to methods all utilise polymorphic_url to generate their paths.
If you find your view logic getting cluttered with if statements like the above, and you're willing to take a hit on the readability of your path in exchange for cleaner looking views or controller actions, polymorphic_path is your friend.

No comments:

Post a Comment