# Using an associated model in an attribute setter

**URL:** <https://www.ruby-forum.com/t/using-an-associated-model-in-an-attribute-setter/151497>\
**Category:** Rails\
**Created:** [October 22, 2008, 7:22am UTC](https://www.ruby-forum.com/t/using-an-associated-model-in-an-attribute-setter/151497 "2008-10-22T07:22:52Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rainer\_Frey](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/50afbb/32.png) [@Rainer\_Frey](https://www.ruby-forum.com/u/Rainer_Frey)\
**Post date:** [October 22, 2008, 7:22am UTC](https://www.ruby-forum.com/t/using-an-associated-model-in-an-attribute-setter/151497/1 "2008-10-22T07:22:52Z")

</div>

Hi,  
I want to use an associated model in an overwritten attribute write  
method. But this fails on create, as the association is not yet  
initialized. Code is:

class Forward \< ActiveRecord::Base  
belongs\_to :domain  
validates\_presence\_of :domain, :destination  
validates\_uniqueness\_of :name, :scope =\> :domain\_id

def destination=(dest)  
dest = dest + ‘@’ + domain.name unless (domain.blank? || dest =~  
/@/)  
write\_attribute :destination, dest  
end  
end

When calling destination= and then save, it works fine, put when  
calling Forward.new(attributes) from the controller, domain yields nil  
in destination=, even though domain is initialized before saving, and  
validation succeeds.

How can I achieve that destination= is executed correctly when creating  
a new Forward?  
I tried the following callback in Forward:  
before\_validation\_on\_create { |record|  
record.destination=record.destination}  
and it seems to work. Is this correct, or might this have some side  
effects? It also seems quite hacky, is there a cleaner way?

Regards  
Rainer Frey

---

<div class="post-metadata">

**Author:** ![Rainer\_Frey](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/50afbb/32.png) [@Rainer\_Frey](https://www.ruby-forum.com/u/Rainer_Frey)\
**Post date:** [October 23, 2008, 4:37am UTC](https://www.ruby-forum.com/t/using-an-associated-model-in-an-attribute-setter/151497/2 "2008-10-23T04:37:57Z")

</div>

On 21 Oct 2008, at 15:56, Rainer Frey wrote:

> validation succeeds.
> 
> How can I achieve that destination= is executed correctly when  
> creating  
> a new Forward?

Forward.new(attributes) boils down to:

- create a blank instance
- attributes.each {|k,v| object.send("#{k}=",v)

hashes are unordered so you can’t rely on domain being set before  
destination is.

Fred

---

<div class="post-metadata">

**Author:** ![Rainer\_Frey](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/50afbb/32.png) [@Rainer\_Frey](https://www.ruby-forum.com/u/Rainer_Frey)\
**Post date:** [October 23, 2008, 3:24pm UTC](https://www.ruby-forum.com/t/using-an-associated-model-in-an-attribute-setter/151497/3 "2008-10-23T15:24:12Z")

</div>

Frederick C. wrote:

> Forward.new(attributes) boils down to:
> 
> - create a blank instance
> - attributes.each {|k,v| object.send("#{k}=",v)
> 
> hashes are unordered so you can’t rely on domain being set before  
> destination is.

Ok, so I need to take care of this afterwards. Any comments on below  
solution/workaround?

> > I tried the following callback in Forward:  
> > before\_validation\_on\_create { |record|  
> > record.destination=record.destination}  
> > and it seems to work. Is this correct, or might this have some side  
> > effects? It also seems quite hacky, is there a cleaner way?

Regards  
Rainer Frey
