Reputation: 1050
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.
Upvotes: 3
Views: 3210
Reputation: 14449
You can avoid this and make things a bit simpler by introducing a Vehicle model. The Vehicle model can have all your PreviousOwners, PreviousPlates, etc collections, and then your Truck, Car and Motorcycle models can has_one Vehicle.
Upvotes: 1
Reputation: 1195
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!
Upvotes: 2
Reputation: 16749
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!
Upvotes: 2
Reputation: 6409
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.
Upvotes: 1
Reputation: 7164
There is a RailsCast on Complex Forms that might help you with building a single form from multiple models.
Upvotes: 1
Reputation: 2018
Very well, nested form builders doesn't have to be associated with nested resources AFAIK.Can you post your models code as well?
Upvotes: 1