首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Mongoid,与带有时间戳和版本控制的嵌入式文档混淆?

Mongoid,与带有时间戳和版本控制的嵌入式文档混淆?
EN

Stack Overflow用户
提问于 2011-04-11 12:34:20
回答 2查看 3.3K关注 0票数 4

我已经使用Mongoid大约3个月了,多亏了很棒的文档和资源,我几乎完成了我需要的任何事情。

但是,为了改进一些我做了几个后退的东西,我在嵌入式文档上肯定有很多困难。

简而言之,我试图做的是维护嵌入式文档的版本控制和时间戳,但我无法做到这一点。

以下是我的模型的相关部分:

代码语言:javascript
运行
复制
class Content
  include Mongoid::Document
  include Mongoid::Timestamps
  include Mongoid::Paranoia

  embeds_many :localized_contents
  accepts_nested_attributes_for :localized_contents
end

class LocalizedContent
  include Mongoid::Document
  include Mongoid::Timestamps
  include Mongoid::Paranoia
  include Mongoid::Versioning

  embedded_in :content, :inverse_of => :localized_contents
end

这里没有什么复杂的东西,关于内容模型的行为一切正常,但是LocalizedContent模型的行为并不像我期望的那样,所以我的期望要么需要调整,要么我需要帮助来纠正我做错了什么。

要创建新的嵌入式文档,我执行以下操作:

代码语言:javascript
运行
复制
my_content = Content.find(params[:id])
my_content.localized_contents.build(params[:localized_content])
if parent.save
 #redirect, etc.
end

这在某种意义上是有效的,它成功地在正确的内容中创建了一个新的嵌入文档,但是我留下的时间戳字段为空

现在,如果我尝试更新该localized_content:

代码语言:javascript
运行
复制
my_content = Content.find(params[:content_id])
localized_content = my_content.localized_contents.find(params[:id])

现在,如果我这样做:localized_content.update_attributes(params[:localized_content]),我会得到以下错误:

代码语言:javascript
运行
复制
=> Mongoid::Errors::InvalidCollection: Access to the collection for LocalizedContent is not allowed since it is an embedded document, please access a collection from the root document.

足够公平,然后我原子地更新本地化内容上的字段,并保存父内容:

代码语言:javascript
运行
复制
localized_content.fieldA = "value"
localized_content.fieldB = "value"
localized_content.fieldC = "value"

my_content.save

这在正确更新本地化内容时有效,但是:-时间流(udpated_at和created_at)仍然为空-版本不会收到当前localized_content的副本,并且版本不会递增!

因此,正如我在这些组和web上的一些论坛中读到的许多场合一样,由于性能原因,嵌入的文档上不会触发回调,因为我在父级上调用save。再说一次,这已经足够了,但正如在这些地方所建议的,我应该在嵌入的文档上调用save…但是怎么做呢!?!?!因为每次我这样做我都会得到可怕的:

代码语言:javascript
运行
复制
=> Mongoid::Errors::InvalidCollection: Access to the collection for LocalizedContent is not allowed since it is an embedded document, please access a collection from the root document.

更重要的是,我尝试在embedded: localized_content.revise上手动回调用于版本控制的回调,但还是出现了相同的错误:

代码语言:javascript
运行
复制
=> Mongoid::Errors::InvalidCollection: Access to the collection for LocalizedContent is not allowed since it is an embedded document, please access a collection from the root document.

我快疯了!请帮帮忙。我做错了什么?应该如何创建和更新嵌入的文档,以便我可以调用(即使是手动的,我也不关心)适当的回调来更新时间戳和版本控制?

谢谢,

亚历克斯

ps:我使用的是rails 3.0.3和mongoid 2.0.1

EN

回答 2

Stack Overflow用户

发布于 2012-04-09 05:50:29

如果这个答案对任何人仍然有用,Mongoid已经添加了一个标签,当父对象被保存时,它可以在嵌入子对象上运行回调。

您的父对象现在应该如下所示:

代码语言:javascript
运行
复制
class Content
  include Mongoid::Document
  include Mongoid::Timestamps
  include Mongoid::Paranoia

  embeds_many :localized_contents, cascade_callbacks: true
  accepts_nested_attributes_for :localized_contents
end

就这样!现在,保存父对象将在子对象上运行回调(并且Mongoid::Timestamps足够智能,只在实际发生更改的对象上运行)。此信息位于mongoid文档中,位于嵌入式文档页面的最底部。

票数 14
EN

Stack Overflow用户

发布于 2011-06-08 03:13:26

尝试使用create而不是build。EmbeddedDoc.build和EmbeddedDoc.new不会触发任何保存回调(因为还没有保存任何内容),保存父文档也不会调用嵌入子文档的回调(性能决策)。不过,EmbeddedDoc.create应该会触发嵌入式文档回调。

代码语言:javascript
运行
复制
my_content = Content.find(params[:id])
puts my_content.localized_contents.create(params[:localized_content])
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5616779

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档