Using Polymorphic urls and paths to create dynamic routes in Ruby on Rails

Posted on 14 August 2010

Dynamic named routes in Ruby on Rails are really useful when you want to generate a url but you don't necessarily know which records it will be for. For example if have a controller action that is used for multiple views in your application. A simple example would be where you have articles, comments and users...

Class Article < ActiveRecord::Base
  has_many :comments
end

Class User < ActiveRecord::Base
  has_many :comments
end

Class Comment < ActiveRecord::Base
  belongs_to :user
  belongs_to :article
end

Now you might have a controller for the comments with an index action that could be used in two ways. Firstly to load the comments for a particular article or secondly to load the comments for a particular user. Let's say you have the following in your routes.rb

ActionController::Routing::Routes.draw do |map|
  map.resources :articles do |article|
    article.resources :comments
  end
  map.resources :users do |user|
    user.resources :comments
  end
end

So now you have two routes to get to each action in the comments controller. For example the edit action...

edit_article_comment GET    /articles/:article_id/comments/:id/edit(.:format) {:action=>"edit", :controller=>"comments"}

edit_user_comment GET    /users/:user_id/comments/:id/edit(.:format) {:action=>"edit", :controller=>"comments"}

So now let's say that on the index action where you list the comments you have an edit link. This is where the polymorphic_url comes in handy to dynamically create url for the correct route.

edit_polymorphic_url([(@article || @user), comment])

Which will result in either edit_article_comment_url or edit_user_comment_url depending on which instance variable is present. Note that there is also new_polymorphic_url and just polymorphic_url The Rails api documentation is well worth a look. Interesting to note that Rails uses polymorphic_url in redirect_to and form_for.

About Paul

Paul works for Kyan web design agency in Surrey, UK as a Ruby on Rails developer.

Follow Paul on Twitter

Email: paulsturgess [at] gmail.com

Read more articles in the archive →

Comments...

  • Wow, didn't know that. Quite useful. Thank you

    Helmut Michael Juskewycz at 27 Aug 10 at 03:36

  • Nice, this looks smart.

    Pete at 21 Sep 10 at 09:26

  • Cool. Never read or seen of this anywhere. Thanks for sharing!

    Dom at 04 Jan 11 at 03:58

  • Great

    Tony at 10 May 11 at 06:17

  • That's very nice, working with _url but as well with _path.
    Thanks

    Daf at 26 Jan 12 at 14:39

Got something to say?