У меня проблема с методом ActiveRecord save_changes, возвращающим пустые значения, когда изменение было инициировано дочерним элементом, обновленным из вложенных атрибутов.
Учитывая эти две модели:
class Customer < ApplicationRecord
enum status: {inactive: 0, active: 1, paused: 2}, _prefix: :status
has_many :customer_pauses
has_many :contracts
after_save :handle_status_change
protected
# UNEXPECTED BEHAVIOR HAPPENS HERE!!!
def handle_status_change
puts "CHANGED STATUS??? #{saved_change_to_status?}"
puts saved_changes
puts "--------------------"
if saved_change_to_status?
contracts.where(status: saved_change_to_status.first).update status: status
end
end
end
class CustomerPause < ApplicationRecord
enum status: {disabled: 0, scheduled: 1, ongoing: 2, finished: 3}, _prefix: :status
belongs_to :customer
after_save :update_customer_status
protected
#update customer status to match the status of the pause accordingly
def update_customer_status
if (saved_change_to_status? || new_record?)
if status_ongoing? && customer.status_active?
customer.update status: Customer::STATUS_PAUSED
end
end
end
end
Происходят эти различия в поведении:
customer = Customer.create status: :active
pause = customer.customer_pauses.create status: :disabled
pause.status = :ongoing
#this works as expected, and customer.saved_changes will contain the status change
pause.save
#This however will result in saved_changes to be empty on the customer callback "handle_status_change"
#Note that the customer status is still changed but not listed in saved_changes
customer.update customer_pauses_attributes: [pause.attributes]
Я не уверен, почему это происходит, это ожидаемое поведение или ошибка в рельсах?
Должен ли быть обратный вызов для вложенного потомкане вызывать изменения у своего родителя?