Please check the pseudocode:
class Team
  has_many :users
  accepts_nested_attributes_for :users, allow_destroy: true
end
class User
  belongs_to :team
  has_many :addresses
  accepts_nested_attributes_for :addresses
  attr_accessor :dummy
  before_validation :generate_addresses_attributes
  def generate_addresses_attributes
    # Use the dummy value to set the addresses_attributes
  end
end
Now when execute team.update(users_attributes: [{"0" => { dummy: "changed!" }}])(the other fields will not change except the dummy attribute), it will not trigger the #generate_addresses_attributes callback since it think there is nothing changes, no save, no callback...
So my question is how to trigger the callback for the virtual attributes, or maybe force save for accepts_nested_attributes_for.
Thank you!
Finally, I found two solution:
add callback in Team model to trigger the callback functional manually
use the attribute_will_change! to override the setter method:
class User
  belongs_to :team
  has_many :addresses
  accepts_nested_attributes_for :addresses
  attr_accessor :dummy
  def dummy=(value)
    attribute_will_change!("dummy") if @dummy != value
    @dummy = value
  end
  ...
end
I found that for Rails 5.1+ attribute works better than attr_accessor for this use case.
attribute dirties up the object, thus triggering callbacks when saving it.
class User
  belongs_to :team
  has_many :addresses
  accepts_nested_attributes_for :addresses
  attribute :dummy, :string
  before_validation :generate_addresses_attributes
  def generate_addresses_attributes
    # Use the dummy value to set the addresses_attributes
  end
end
                        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