Open Tao-Galasse opened 1 year ago
Documentation only mentions using this as the parent class (via has_one and has_many). When using it that way (define the accepts_nested_attributes_for
in supplier).
supplier = Supplier.create(name: ‘Supplier 1’, account_attributes: …)
dirty works as intended (supplier.account.saved_changes
).
However, I would like to be able to use supplier.saved_changes
and see what has changes with account IFF I made those modifications via the nested attributes helpers.
My thought is to enable an option on accepts_nested_attribute_for
, such as nest_dirty: true
, which would show changes made to associations modified via the helper. I.e.
supplier = Supplier.create(name: ‘supplier 1’, account_attributes: { name: “account 1” })
supplier.saved_changes
# => { id: [nil, 1], name: [nil, ‘supplier 1’], account: { id: [nil, 1], name: [nil, ‘account 1’] } }
Since conceptually the accepts_nested_attributes_for
helper is creating a model writer which can be dirtied, I think this would be within their respective domains.
@Tao-Galasse in your example, you update the name of the supplier only account.update(supplier_attributes: { name: 'new supplier' })
why do you expect the account
instance to have a different supplier_id?
I expect account.saved_changes to return something like {"supplier_id"=>[1, 2]}
How come updating the name could change the ID too?
@saiqulhaq because i didn't update the existing supplier here, I created a new one.
If I wanted to update the existing one, I should have passed its ID in the supplier_attributes
, like this :
account.update(supplier_attributes: { id: account.supplier_id, name: 'update my supplier' })
ok I got it
I also found that there is update_only
for one on one associations to force always updating the existing record
and found this one https://discuss.rubyonrails.org/t/rails-dirty-object-concept-is-not-working-with-nested-att/54505 that raised at 2010
I think the feature to check the saved changes on nested has one and has many won't be implemented because the cost is high
what you can do is enumerate each nested record and check the saved_changes data see https://github.com/saiqulhaq/rails-issue-test-cases/blob/c7885ddda73ea537f41a8a212d14b7a9269e7461/project/48291.rb#L82 as an example
In my real life case, I cannot use the update_only: true
because my nested record could be shared on other objects where it must not be updated.
But thanks a lot for the example, it could be useful in the future :)
Steps to reproduce
I have those two classes (same example than the
has_one
association documentation from the Active Record Associations guide) :and I am updating the supplier from the account like this :
account.update(supplier_attributes: { name: 'new supplier' })
See this test in my dummy app => https://github.com/Tao-Galasse/rails-test-app/blob/main/test/models/account_test.rb
Expected behavior
I expect
account.saved_changes
to return something like{"supplier_id"=>[1, 2]}
Actual behavior
account.saved_changes
returns an empty hash{}
System configuration
Rails version: Tested with Rails 6.1.7.2 & Rails 7.0.4.2
Ruby version: 3.2.0