I have a polymorphic association that looks like this:

class Line < ActiveRecord::Base
   belongs_to :item, :polymorphic => true

class Education < ActiveRecord::base
   has_many :lines, :as => :item

class Work < ActiveRecord::base
   has_many :lines, :as => :item

I'd like a simple way to create a new Line from the parent Item. So, I might be editing a view for a Work object, and want to have a link that creates a new Line object. Normally, I would do this:

<%= link_to "New Line", new_work_line_path(@work) %>

And the helper would work the route for this. However, this requires that I check which parent the Line belongs to in the controller, defeating the purpose of polymorphism (I could have used two references if that were the case). So, my question is, how do I get the path to work polymorphically like a normal path helper?

  • 1
    "What I'm looking for is a way to be in a view for, say, a work object, and create new Line to go in it." This sentence confuses me greatly. Care to rephrase? – Jamie Wong Jun 30 '10 at 1:51
  • I edited the question to be clearer. – Zoe Jul 1 '10 at 18:06

A possible way could be to use routes like this:

map.resources :works do |works|
  works.resources :lines

map.resources :educations do |edu|
  edu.resources :lines

Your LinesController remains the same, and you'll get routes like these:

work_lines GET    /works/:work_id/lines
education_lines GET    /educations/:education_id/lines

The most annoying part is to manage the first id passed, because you'll have a params[:id] referred to a Line, but you'll also have params[:work_id] or params[:education_id]. Here you must choose between checking which param is passed, or at least parse the requested url to determine in which you are (Works, Educations, etc...).

Hope this helped ;)


According to what emerged in comments, you can use polymorphic_url/polymorphic_path (http://api.rubyonrails.org/classes/ActionDispatch/Routing/PolymorphicRoutes.html):

It makes sense if you use them like this way:

link_to "New Line", polymorphic_url(@line.item,@line)
# => /<educations_or_works>/item_id/lines/line_id

At least, you can even use it for collections:

link_to "New Line", polymorphic_url(@line.item,Line.new)
# => /<educations_or_works>/item_id/lines/


  • 1
    This is a way to do this, but it's not polymorphic at all. I've found a lot of variations on this, and it seems like polymorphic associations were included in ActiveRecord, but completely forgotten in every other place. I was hoping that wasn't actually the case, and I just looked in the wrong places. I'll keep this in mind if I can't find anything else, though. – Zoe Jul 1 '10 at 18:08
  • I showed you routes mantaining your polymorphyc model associations. – Andrea Pavoni Jul 2 '10 at 8:02
  • right, but the routes don't behave polymorphically, which is what I'm looking for. The route is specific to whether the Line belongs to a Work or an Education, as is the result in the controllor (:word_id and :education_id). Because both of these are supposed to be associated with lines as an Item object, it would make sense if there were a way to get an :item_id in there that could represent either Work or Education. – Zoe Jul 2 '10 at 15:35
  • Thank you ^_^ Thats the perfect answer. – Zoe Jul 2 '10 at 22:26
  • Just tumbled onto this.... if you are still on Rails 2.3.x (2.3.5 in my case), then the correct way to call the method is polymorphic_path|url([@line.item, @line])... noting the array parameter – Nazar Jun 16 '11 at 12:39

Your Answer

