2010-11-23 7 views

Antwort

1

Ich glaube nicht, Mongoid eigene schmutzige Attribute Feature Änderungen an eingebetteten Dokumenten verfolgt. Aber es ist nicht schwer, grundlegende schmutzig Verfolgung von eingebetteten Dokumente, sich mit so etwas zu implementieren:

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 

Wenn Sie mehr Optionen benötigen, wie eingebettete Dokumente Änderungen einschließlich in Bar.changes oder die spezifischen Änderungen Tracking, haben Sie außer Kraft setzen die changes und changed? Methoden, die ich nicht tun würde, wenn Sie diese Funktionen absolut benötigen.

Hier ist eine Art und Weise zu verfolgen, was in den eingebetteten Dokumente geändert:

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 
+0

Danke für die Antwort. Es war fast ich wollte mit ein paar extra Sachen. – Autodidact

+0

Was ich möchte ist, wann auch immer sich foo ändert, möchte ich über die bar wissen.geändert? und bar.changes, um diese Werte zu geben. Ich denke, wie Sie gesagt haben, mein Bedürfnis, die Änderungen zu überschreiben und zu ändern? Methoden. Aber wie geht das? – Autodidact

+0

Siehe die aktualisierte Antwort oben. Seien Sie jedoch vorsichtig, wenn Sie 'changes' und' changed' übersteuern. Mit komplexen Dokumenten könnten seltsame Dinge passieren. Es gibt einen Grund, warum Mongoid nur schmutzige Attribute und keine schmutzigen Assoziationen verfolgt. – bowsersenior

2

Ich habe mongoid Erweiterung zusammen https://github.com/versative/mongoid_relations_dirty_tracking dieses Problem zu lösen. Es verfolgt einfach Änderungen an Dokumentrelationen in der gleichen Weise wie Mongoid es für Attribute tut, so dass die Zeitstempel und Versionen korrekt aktualisiert werden.

+0

Dies funktioniert nicht mit Mongoid 6 und Schienen 5. –