Using an associated model in an attribute setter

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

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?

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

Frederick Cheung 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