Using an associated model in an attribute setter


#1

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


#2

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


#3

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