# Handling of relations belongs\_to/has\_many

**URL:** <https://www.ruby-forum.com/t/handling-of-relations-belongs-to-has-many/66711>\
**Category:** Rails\
**Created:** [August 28, 2006, 4:27pm UTC](https://www.ruby-forum.com/t/handling-of-relations-belongs-to-has-many/66711 "2006-08-28T16:27:00Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![thomas](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e36b37/32.png) [@thomas](https://www.ruby-forum.com/u/thomas)\
**Post date:** [August 28, 2006, 4:27pm UTC](https://www.ruby-forum.com/t/handling-of-relations-belongs-to-has-many/66711/1 "2006-08-28T16:27:00Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![thomas](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e36b37/32.png) [@thomas](https://www.ruby-forum.com/u/thomas)\
**Post date:** [August 29, 2006, 12:37am UTC](https://www.ruby-forum.com/t/handling-of-relations-belongs-to-has-many/66711/2 "2006-08-29T00:37:06Z")

</div>

> ```
> ....
> 
> ```
> 
> 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

---

<div class="post-metadata">

**Author:** ![thomas](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e36b37/32.png) [@thomas](https://www.ruby-forum.com/u/thomas)\
**Post date:** [August 29, 2006, 7:19am UTC](https://www.ruby-forum.com/t/handling-of-relations-belongs-to-has-many/66711/3 "2006-08-29T07:19:41Z")

</div>

Max,

On 8/29/06, Max M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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

---

<div class="post-metadata">

**Author:** ![thomas](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e36b37/32.png) [@thomas](https://www.ruby-forum.com/u/thomas)\
**Post date:** [August 29, 2006, 11:44am UTC](https://www.ruby-forum.com/t/handling-of-relations-belongs-to-has-many/66711/4 "2006-08-29T11:44:43Z")

</div>

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
