form question

Suppose I have the following models/migrations:

class Car < ActiveRecord::Base
  belongs_to :manufacturer
  validates_presence_of :manufacturer
  validates_association :manufacturer

class CreateCars < ActiveRecord::Migration
  def self.up
    create_table cars do |t|
      t.column :name, :string
     t.column :manufacturer_id, :integer

class Manufacturer < ActiveRecord::Base
  has_many :cars

class CreateManufacturers < ActiveRecord::Migration
  def self.up
    create_table maufacturers do |t|
      t.column :name, :string

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)

def manufacturer_name

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)
    self.manufacturer = m

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)

def manufacturer_name

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: