embeds_many字段

时间:2016-04-20 12:07:07

标签: mongodb ruby-on-rails-4 mongoid atomicity

使用rails4mongoidembeds_many MyEmbed模型的MyModel关系我需要进行原子更新,因此embed.status of latests插入字段将重写旧的嵌入字段状态。当然,我需要在原子操作中使用它,因为它会带来不一致。

示例:

my_embed.rb

class MyEmbed
  include Mongoid::Document
  include Mongoid::Timestamps

  STATUS_ACTIVE = 1
  STATUS_INACTIVE = 3

  field :data,         type: String
  field :status,       type: Integer, default: STATUS_ACTIVE

  embedded_in :my_model
end

my_model.rb

class MyModel
  include Mongoid::Document
  include Mongoid::Timestamps

  embeds_many :my_models, order: :created_at.desc

  field :data,         type: String
end

并且

mymodel = MyModel.new(data: 'data')
mymodel.save!

mymodel.my_embeds.create!(data: 'Dummy data')

然后在下一次创建embed字段时,我希望自动将旧状态更新为非活动状态。

任何想法?

1 个答案:

答案 0 :(得分:0)

嵌入式文档本质上是包含json的数组,但您仍然可以对它们执行原子更新。您可以在此处阅读原子更新(https://docs.mongodb.org/ecosystem/tutorial/mongoid-persistence/#atomic

因此,您可以执行以下操作:

my_model = MyModel.create(data:'this is my model')
=> #<MyModel _id: 57175de579acba0f1ea0dd30, created_at: 2016-04-20 10:45:57 UTC, updated_at: 2016-04-20 10:45:57 UTC, data: "this is my model", _type: "MyModel">
my_model.my_embeds.create(data: 'this is my embed', status:'created')
=> #<MyEmbed _id: 56935de579acba0f1ea0dd30, created_at: 2016-04-20 10:45:59 UTC, updated_at: 2016-04-20 10:45:59 UTC, data: "this is my embed", status:'created', _type: "MyEmbed">
my_model.my_embeds.count
=> 1
my_model.data
=> 'this is my model'
my_model.my_embeds.first.data
=> 'this is my embed'
my_model.my_embeds.first.status
=> 'created' 
my_model.my_embeds.first.set(status:'updated')
=> #<MyEmbed _id: 56935de579acba0f1ea0dd30, created_at: 2016-04-20 10:45:59 UTC, updated_at: 2016-04-20 10:46:03 UTC, data: "this is my embed", status:'updated', _type: "MyEmbed">
my_model.my_embeds.first.status
=> 'updated'

关于使用&#39; first&#39;的说明,在最新的mongo中你需要在前面放一个排序,例如.asc(:_ id)和mongoid 5一样,没有添加任何排序。自动。

更新:问题已更新,答案也是如此。

我假设你告诉你你是原子地更新,你不是在嵌入创建(https://docs.mongodb.org/ecosystem/tutorial/mongoid-callbacks/)上自动(即通过回调)。

假设这是真的,你只想这样做:

my_model = MyModel.create(data:'this is my model')
=> #<MyModel _id: 57175de579acba0f1ea0dd30, created_at: 2016-04-20 10:45:57 UTC, updated_at: 2016-04-20 10:45:57 UTC, data: "this is my model", status:1, _type: "MyModel">
my_model.my_embeds.create(data: 'this is my embed')
=> #<MyEmbed _id: 56935de579acba0f1ea0dd30, created_at: 2016-04-20 10:45:59 UTC, updated_at: 2016-04-20 10:45:59 UTC, data: "this is my embed", _type: "MyEmbed">
my_model.my_embeds.count
=> 1
my_model.set(status:MyModel::STATUS_INACTIVE)
=> #<MyModel _id: 57175de579acba0f1ea0dd30, created_at: 2016-04-20 10:45:57 UTC, updated_at: 2016-04-20 10:45:59 UTC, data: "this is my model", status:3, _type: "MyModel">

回答评论:

根据您提出的问题,您的问题有两种可能的答案。你在询问交易吗?回滚或关于原子地更新多个字段。我相信你在问两个更简单的问题,那就是你如何原子地更新多个字段。

这只是传递了多个字段,如下所示:

my_model.set(status:MyModel::STATUS_INACTIVE, data:'atomically update this as well')
=> #<MyModel _id: 57175de579acba0f1ea0dd30, created_at: 2016-04-20 10:45:57 UTC, updated_at: 2016-04-20 10:45:59 UTC, data: "atomically update this as well", status:3, _type: "MyModel">