Suppose I have the following models/migrations: class Car < ActiveRecord::Base belongs_to :manufacturer validates_presence_of :manufacturer validates_association :manufacturer end class CreateCars < ActiveRecord::Migration def self.up create_table cars do |t| t.column :name, :string t.column :manufacturer_id, :integer end end class Manufacturer < ActiveRecord::Base has_many :cars end class CreateManufacturers < ActiveRecord::Migration def self.up create_table maufacturers do |t| t.column :name, :string end end Now, I need a form to create new Cars that has two text fields: name, and manufacturer. I can't use a select for manufacturer, because there are far too many of them (let's pretend). What I can't figure out is how to construct the text_field helper tag in my form such that Rails understands that the form field doesn't map directly to a field in the Car object, but rather to the name field of the car's Manufacturer object. Is there even a way to do it? I'm looking for something like one of these (neither of which work, obviously, but they may help to clarify what I'm trying to do): <%= text_field 'car', 'car.manufacturer.name' %> or <%= text_field 'car', 'car.manufacturer[:name]' %> Without the ability to do that, I'm not sure how I could have - for example - an edit form without writing special code to populate that field, or how any of the validates_* methods would work. I've tried using fields_for, but it doesn't work; probably because I'm not doing it right. Maybe someone knows how to use fields_for to accomplish the above? I think what I tried was something like this: <% fields_for :manufacturer, @car.manufacturer do |m_field| %> <%= m_field.text_field :name %> <% end %> -- Bill K.
on 2007-05-20 00:45
on 2007-05-20 02:44
One thing you can do is define a pair of methods on the car object something like this (off the top of my head). def manufacturer_name=(value) manufacturer.create(:name => value) end def manufacturer_name manufacturer.name end
on 2007-05-20 03:31
On May 19, 6:44 pm, dasil003 <firstname.lastname@example.org> wrote: > One thing you can do is define a pair of methods on the car object > something like this (off the top of my head). > > def manufacturer_name=(value) > manufacturer.create(:name => value) > end > > def manufacturer_name > manufacturer.name > end Won't manufacturer.create store a new manufacturer in the manufacturers table? In my case, they're all pre-defined. Users populating this form aren't creating a new one, they're typing the name of one that should already exist, after which I validate. But on that note, I did try something like this: def manufacturer=(m) if m.instance_of? String self.manufacturer = Manufacturer.find_by_name(m) else self.manufacturer = m end end Of course, this resulted in an endless loop. Woops. -Bill K.
on 2007-05-20 04:57
On May 19, 7:30 pm, Bill K. <email@example.com> wrote: > > manufacturer.name > > end > > Won't manufacturer.create store a new manufacturer in the > manufacturers table? In my case, they're all pre-defined. Actually, you've pretty much nailed it. I set my form up like: <%= text_field_for 'car', 'manufacturer_name' %> And in Car: def manufacturer_name=(m) self.manufacturer = Manufacturer.find_by_name(m) end def manufacturer_name self.manufacturer.name end This seems to do pretty much exactly what I was trying to accomplish, and my validates_presence_of works. The only thing that doesn't work is validates_associated :manufacturer, because when an invalid manufacturer name is entered it isn't found in the database, so manufacturer remains nil and the validates_presence_of fails instead. But I can live with that. Thanks for the brain kick. :) -Bill