【问题标题】:Mongoid 4 update array attribute in a documentMongoid 4更新文档中的数组属性
【发布时间】:2014-07-21 16:27:01
【问题描述】:

这段代码中无法更新文档中的数组的错误是什么?

型号

class Foo
  include Mongoid::Document
  include Mongoid::Timestamps::Created

  field :myarray, type: Array

end

控制器

def add_item
        @foo = Foo.find_by(uuid: params[:uuid])
        unless @foo.nil?
            unless @foo.has_attribute? :myarray
                @foo[:myarray] = Array.new
            end
            @foo[:myarray] << params[:item]
            @foo.save
        end
end

我正在使用带有 MongoId 4 的 Rails 4,如果我在 @foo.save 之前使用 p @foo,我可以看到 @foo 正确更改,但由于任何原因更新不会持续。

【问题讨论】:

  • 如果您改为@foo[:myarray] += [ params[:item] ] 会怎样?
  • 这行得通!但我不明白为什么有必要再次实例化数组以跟踪 mongoid 的变化。

标签: arrays ruby-on-rails-4 mongoid mongoid4


【解决方案1】:

当你这样说时:

@foo[:myarray] << params[:item]

您正在就地修改 myarray 数组,因此 Mongoid 可能无法识别它已更改。然后当你说@foo.save时,Mongoid会查看@foo,看看有什么变化;但是@foo[:myarray] 中的数组引用不会改变,所以 Mongoid 会判断没有任何改变,@foo.save 不会做任何事情。

如果您通过以下方式强制创建新的数组引用:

@foo[:myarray] += [ params[:item] ] # Or anything else that creates a whole new array

然后 Mongoid 将注意到 @foo[:myarray] 已更改,@foo.save 将通过基础文档上的 $set 操作将更改发送到 MongoDB。

这看起来像是 PostgreSQL 数组列的 ActiveRecord 问题的 Mongoid 版本:

New data not persisting to Rails array column on Postgres

经验法则是“不要就地编辑可变值,而是创建全新的值:复制、编辑、替换”。这样您就不必担心手动管理“脏”标志。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-27
    • 1970-01-01
    • 1970-01-01
    • 2014-03-20
    • 1970-01-01
    相关资源
    最近更新 更多