views:

1050

answers:

5

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.

+1  A: 

Very well, nested form builders doesn't have to be associated with nested resources AFAIK.Can you post your models code as well?

Hemant Kumar
+1  A: 

There is a RailsCast on Complex Forms that might help you with building a single form from multiple models.

Bryan Woods
Isn't that outdated, with Rails' new 'accepts_nested_attributes_for' stuff?
Baby Diego
+1  A: 

If the car/motorcycle/truck models are identical, you should add a type column to your vehicle model. If they're not, you should use STI (single table inheritance).

But yeah, need to see your models first before I can give you code.

zaius
+1  A: 

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!

ole_berlin
+1  A: 

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!

Preston Marshall
It works one way but not the other. Your situation doesn't make a difference at all because Upload knows it only has task to deal with. Try other way round would be not possible because the belongs_to relations is polymorphic which logically, rails won't know how to determine what to create. I kinda stuck with this one too.
goodwill