I am not sure if this is a bug in ActiveRecord or is this the intended behavior. If it is then it does not make sense to me.
In a nutshell: If you change an aggregate object attribute created via composed_of method (see Agile Web Development - Second Edition Chapter 17 page 313 onwards) and then save the model, the change to the model (composite attribute specifically) will not be saved UNLESS you explicitly set the partial_updates attribute for that model to false. N Specific use-case:
I have an Account model that shadows the accounts table in database. This account object contains a composite object (amongst others) called BillingAddress defined within the Account model class as follows:
composed_of :billing_address, :mapping => [%w(address_1 address_1), %w(address_2 address_2), %w(address_3 address_3), %w(city city), %w(state state), %w(zip zip), %w(card_country country)] do |params| BillingAddress.new params end
To test this theory, in the Rails Console, I "found" and existing Account object in the database using
acct = Account.find(id) -- where id is a specific account id
Now I create a billing address object:
ba = BillingAddress.new("123 Lane", nil, nil, "City", "State", "12345", "USA")
Next, I assigned the newly created billing object to the account object's billing_address composite attribute as follows:
acct.billing_address = ba
Now if I save this as:
acct.save
Then no update statement is triggered as it does in Rails 2.0.2.
If however, I set the partial_updates for the Account class to false BEFORE assigning the ba value to acct.billing_address then the update statement is triggered. That is:
Account.partial_updates = false acct.billing_address = ba acct.save
This will trigger the update which is what I want.
Note that partial_updates works as stated for simple attribute updates. That is:
Account.partial_updates = true acct.address_1 = 'xyz street' acct.save
correctly triggers the partial update where only the address_1 attribute is updated in the database.
Has anyone else experienced a similar problem with composite attributes?
Bharat