Handling of relations belongs_to/has_many

Hi,

I'm fairly new to RoR and I think I don't get some of the ActiveRecord magic.

I have:

# a lookup table (used to show countries in a <select>) class Country < ActiveRecord::Base   has_many :breeders   validates_presence_of :name end

# a table of companies (each located in a specific country). class Breeder < ActiveRecord::Base   belongs_to :country   validates_presence_of :name   validates_associated :country # may be NIL when we don't know it yet end

Currently, I do in the controller to create or update a Breeder:

  def create     p=params[:breeder]     country_id = p[:country_id]     @breeder = Breeder.new(p)     @breeder.country = country_id.blank? ? nil : Country.find(country_id)     if @breeder.save     ....

What exactly is the difference for @breeder.country when it's assigned a (found) Country or breeder.country_id is set by Breeder.new(params[:breeder]) ?

Both save the country_id to the "breeders" table; besides that, the Breeder "knows" that the country_id (may) refer to a country and could do the find above itself.

Regards,

Thomas

Currently, I do in the controller to create or update a Breeder:

  def create     p=params[:breeder]     country_id = p[:country_id]     @breeder = Breeder.new(p)     @breeder.country = country_id.blank? ? nil : Country.find(country_id)     if @breeder.save     ....

What exactly is the difference for @breeder.country when it's assigned a (found) Country or breeder.country_id is set by Breeder.new(params[:breeder]) ?

There is no difference, except that your controller code gets unneccessarily verbose.

The following should work just fine:

  def create      @breeder = Breeder.new(params[:breeder])      if @breeder.save

Much simpler.

AR lazily initialises the breeder.country field on first access and internally performs a Country.find(breeder.country_id). Conversely, if you set the country field, country_id is updated.

In short, don't bother with finding and setting the country yourself.

Cheers, Max

Max,

The easiest workaround would be to validate yourself.

class SomeModel   def validate     errors.add 'some_attribute', 'cannot be blank' unless self.some_attribute   end end

Cheers, Max