Я не думаю, что собственная функция грязных атрибутов Mongoid отслеживает изменения во встроенных документах.Но несложно реализовать базовое грязное отслеживание встроенных документов самостоятельно с помощью чего-то вроде этого:
class Bar
include Mongoid::Document
embeds_many :foos
attr_accessor :foos_changed
alias_method :foos_changed?, :foos_changed
# ...
end
class Foo
include Mongoid::Document
embedded_in :bar, :inverse_of => :foos
after_save :notify_parent
def notify_parent
bar.foos_changed = true
end
# ...
end
b = Bar.create
b.foos_changed? # => nil
b.foos.create
b.foos_changed? # => true
Если вам нужны дополнительные параметры, такие как включение изменений встроенных документов в Bar.changes
или отслеживание конкретных изменений, вы 'Вам придется переопределить методы changes
и changed?
, чего бы я не сделал, если бы вам не требовались эти функции.
Вот способ отследить, что изменилось во встроенных документах:
class Bar
include Mongoid::Document
embeds_many :foos
attr_writer :embedded_changes
def embedded_changes
@embedded_changes ||= begin
self._children.inject({}) do |memo, child|
memo.merge(
{child.collection_name => {child.id => child.changes}}
) if child.changed?
end
end
end
def changes
original_value = super
if original_value.blank?
embedded_changes
else
original_value.merge(embedded_changes)
end
end
def changed?
super || self._children.any?(&:changed?)
end
# ...
end
class Foo
include Mongoid::Document
embedded_in :bar, :inverse_of => :foos
# ...
field :hat
end
b = Bar.create
f = b.foos.create
b.changes # => nil
b.changed? # => false
f.hat = 1
f.changes # => {"hat"=>[nil, "1"]}
b.changes # => {"foos"=>{BSON::ObjectId('4cf...')=>{"hat"=>[nil, "1"]}}}
b.changed? # => true