Uploaded image for project: 'Mongoid'
  1. Mongoid
  2. MONGOID-1278

[field]_will_change! still does not work for arrays

    • Type: Icon: Task Task
    • Resolution: Done
    • 2.3.1
    • Affects Version/s: None
    • Component/s: None

      class ChangeTester
      include Mongoid::Document
      field :visit_stats, type: Array, default: []
      end

      irb(main):001:0> ChangeTester.delete_all
      => 1
      irb(main):002:0> t = ChangeTester.create(visit_stats: [

      {key_name: 'initial'}

      ])
      => #<ChangeTester _id: 4e7c57b28a364c07c1000001, _type: nil, visit_stats: [{:key_name=>"initial"}]>
      irb(main):003:0> t.visit_stats_will_change!
      => [{:key_name=>"initial"}]
      irb(main):004:0> t.visit_stats.each

      {|item| item[:key_name] = 'in-place'}

      => [{:key_name=>"in-place"}]
      irb(main):005:0> t.changes
      => {}
      irb(main):006:0> t.changed_attributes
      => {"visit_stats"=>[{:key_name=>"in-place"}]}

      The consequence of such behavior is that in-place changes to array can't be saved. The problem is that changed_attributes are stuck at array reference instead of cloned value (though AR code dutifully clones).

      Direct assignment works well:

      irb(main):001:0> ChangeTester.delete_all
      => 1
      irb(main):002:0> t = ChangeTester.create(visit_stats: [

      {key_name: 'initial'}

      ])
      => #<ChangeTester _id: 4e7c58558a364c081d000001, _type: nil, visit_stats: [{:key_name=>"initial"}]>
      irb(main):003:0> t.visit_stats_will_change!
      => [{:key_name=>"initial"}]
      irb(main):004:0> t.visit_stats = [

      {key_name: 'assigned'}

      ]
      => [{:key_name=>"assigned"}]
      irb(main):005:0> t.changes
      => {"visit_stats"=>[[{:key_name=>"initial"}], [{:key_name=>"assigned"}]]}

      I believe this is not a Mongoid bug per se, but incompatibility of AR code with complex datatype. It should be handled, though. Perhaps Mongoid should override will_change!, detect if array is in place, and store some extra info which is checked before save.

            Assignee:
            durran Durran Jordan
            Reporter:
            dbulic dbulic
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: