Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access and submit related polymorphic models in the same form, in Rails?

Suppose I have 3 models, Car, Motorcycle and Truck, and for each I have to enter a bunch of stuff, such as a list of known previous owners, traffic tickets, license plates, etc. So I created a model for each (PreviousOwners, PreviousPlates, etc) and set up polymorphic associations for the related models.

The problem is, how can I enter all of that using just one form, kind of like this:

Car #123

Known previous owners:
Jason Jazz
Brian Bass [add another]

Known previous license plates:
12345
67890 [add another]

Current status:
Cleared 
(this is a dropdown select menu, CurrentStatus is also a polymorphic association, but with predefined values.)

etc

This is proving to be a bitch, way beyond my level of expertise (newbie here). The resources are not nested and almost everything I find on multiple models is for nested resources, and nothing seems to apply to polymorphic associations.

(This is just an example, I know ideally I should have a Vehicle model with 'Car', etc, as categories, but it's just to illustrate the real need for polymorphic models in my case.)

Thanks.

like image 345
San Diago Avatar asked Nov 17 '25 00:11

San Diago


2 Answers

Maybe the PresenterPattern is helpfull too:

http://blog.jayfields.com/2007/03/rails-presenter-pattern.html

The basic idea is to create a presenter which acts like a model and processes all the incoming data from your form and distributes it to the models. This way it's also easy to create multiple instances of lets say PreviousOwner and attach it to Car.

Check the link out!

like image 157
Ole Spaarmann Avatar answered Nov 19 '25 14:11

Ole Spaarmann


You can use the new nested attributes in Rails 2.3, but there is a certain way you have to write it to make it work. The trick is that you need to create the actual polymorphic object, then build the class that has the belongs to polymorphic clause in it. This is an example I found at Ryans Scraps, posted by a user named: Superslau (I've cleaned it up a good bit for here):

This feature is really awesome. I have implemented this with polymorphic associations, and it works!

 class Task < ActiveRecord::Base
   has_many :assets, :dependent=>:destroy
   accepts_nested_attributes_for :assets, :allow_destroy => true
   belongs_to :workable, :polymorphic => true
 end



 class Upload < ActiveRecord::Base
   has_one :task, :as => :workable, :dependent=>:destroy
   accepts_nested_attributes_for :task, :allow_destroy => true 
 end

Upload is a kind of task. All tasks can have one or more assets uploaded.

I took me a while to figure out that I should use the Upload model as the parent. So in one form, I can create an upload, and it’s corresponding task entry, along with a file upload.

in my controller:

 def new   
  @upload = Upload.new  
  @upload.task = Task.new  
  @upload.task.assets.build 
 end 

Don’t worry if that doesn’t make any sense, I just wanted to let people know that accepts_nested_attributes_for works just fine with polymorphic associations. Thanks Eloy!

like image 22
Preston Marshall Avatar answered Nov 19 '25 13:11

Preston Marshall