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 )

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§
@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

....

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,

On 8/29/06, Max M. [email protected] wrote:

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.

Thank you very much. I already supposed it should work in this way, but
was
looking for assurance.
However, an ugly bug in validates_associated allows invalid (not null)
foreign keys to be saved in the database. Now I’m prepared for finding a
better workaround for this.

Regards,

Thomas

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