form question

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', '' %> 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 %>

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 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 Kocik

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 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. :slight_smile: