I had a friend email me a week or so ago about generating a link from your restful routes when you don’t know the class. Here’s a quick thumbnail of the scenario.

You have a bunch of restful routes like these:

1
2
map.resources :users
map.resources :groups

And you have a model that has a polymorphic association, meaning that it has an associated value that can be from more than one model. Here’s an example of how that’s done.

1
2
3
4
5
6
7
8
9
10
11
class Post < ActiveRecord::Base
  belongs_to :owner, :polymorphic => true
end
 
class User < ActiveRecord::Base
  has_many :posts, :as => :owner
end
 
class Group
  has_many :posts, :as => :owner
end

Now, let’s say that when you show a post, you want to provide a link to the owner of the post when you display it on its show page. You know that because you’ve provided the restful routes in your config/routes.rb file as show above, you get the nice functionality of the user_path and the group_path methods. The problem is that because you don’t know if @post.owner is a user or a group.

You could conditionally call one of the methods:

1
  <%= link_to @post.owner.name, @post.owner.is_a?(User) ? user_path(@post.owner.id) : group_path(@post.owner.id) %>

That’s a little messy, but it works. The solution I suggested was a little more elegant, but still a little messy:

1
  <%= link_to @post.owner.name, eval "#{@post.owner.class.to_s.underscore}_path(#{@post.owner.id})" %>

It removed the conditionals, but it’s not very clear to read. It turns out that he found a solution already baked into Ruby on Rails:

1
  <%= link_to @post.owner.name, polymorphic_path(@post.owner) %>

You can find documentation on the polymorphic_path method on RailsBrain.

You’ll find that polymorphic_path also supports other forms of the path helpers such as edit_polymorphic_path, new_polymorphic_path, and formatted_polymorphic_path.

I also got information from railspikes.com.

  • DZone
  • Twitter
  • Slashdot
  • Delicious
  • Digg
  • Technorati Favorites
  • Facebook
  • Reddit
  • StumbleUpon
  • LiveJournal
  • Squidoo
  • Google Bookmarks
  • LinkedIn
  • Share/Bookmark

2 Comments »

Philippe Creux

July 22, 2009

We followed the same process starting with something dirty and ending up on something clean. I think you might even remove the call to ‘polymorphic_path’.

link_to @post.owner.name, @post.owner should work as well. :)

Srikanth

September 6, 2009

Great Article.
Thanks :)

Leave a comment