I have two models with a one to many association. I want to set a default value on the child model at initialization based on some state of the parent. This involves having an after_initialize callback fire on the child that needs to access the parent through the belongs_to association. The problem is that when I instantiate the child using the build method, the association to the parent is nil in the after_initialize callback. Is this expected behaviour? I'm on rails 3.0.6
A toy example:
class Merchant < ActiveRecord::Base
has_many :products
end
class Product < ActiveRecord::Base
belongs_to :merchant
after_initialize :set_default_value
def set_default_value
if merchant.state
self.foo = some_value
else
self.foo = some_other_value
end
end
end
And in a controller:
product = merchant.products.build
In the call to set_default_value, merchant is nil though it seems that it shouldn't be.
I would change the code as follows:
class Product < ActiveRecord::Base
...
def set_default_value(state = merchant.state)
if state
self.foo = some_value
else
self.foo = some_other_value
end
end
end
Then change your caller to:
product = merchant.products.build(:state => merchant.state)
Also, I've found after_initialize callbacks to be slow. So another option is to move the logic into the builder for the product.
product = merchant.products.build(:foo => merchant.state ? some_value : some_other_value)
This also eliminates the Law of Demeter violation from the code (i.e. the Product shouldn't know/care what the merchant's state is).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With