【问题标题】:Mongoid, confused with embedded document with timestamps and versioning?Mongoid,与带有时间戳和版本控制的嵌入式文档相混淆?
【发布时间】:2011-04-11 04:34:19
【问题描述】:

我已经使用 Mongoid 大约 3 个月了,由于那里有很棒的文档和资源,我已经设法完成了几乎所有我需要的事情。

但是回过头来改进一些我已经做了几次的东西,我肯定在嵌入式文档上遇到了很多困难。

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

这是我模型的相关部分:

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

这里没什么复杂的,关于 Content 模型的行为一切正常,但是 LocalizedContent 模型的行为并不符合我的预期,所以我的期望要么需要理顺,要么我需要帮助修复我做错了什么。

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

my_content = Content.find(params[:id])
my_content.localized_contents.build(params[:localized_content])
if parent.save
 #redirect, etc.
end

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

现在,如果我尝试更新本地化内容:

my_content = Content.find(params[:content_id])
localized_content = my_content.localized_contents.find(params[:id])

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

=> 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.

很公平,然后我自动更新本地化内容上的字段并保存父项:

localized_content.fieldA = "value"
localized_content.fieldB = "value"
localized_content.fieldC = "value"

my_content.save

这可以正确更新本地化内容,但是: - timesteamps(udpated_at 和 created_at)仍然为零 - 版本没有收到当前本地化内容的副本,并且版本没有增加!

因此,正如我在该组和网络上的某些论坛上多次阅读的那样,出于性能原因,不会在嵌入式文档上触发回调,因为我在父级上调用 save。再一次,足够公平,但正如那些地方所建议的那样,我应该在嵌入式文档上调用 save ......但是如何!?!?!因为每次我都会感到害怕:

=> 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.

更重要的是,我尝试手动回调我的嵌入式版本控制的回调:localized_content.revise,再次出现同样的错误:

=> 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

【问题讨论】:

  • 为您的帖子提供一个合理的主题可能是获得帮助的第一步。诸如“请帮助”之类的内容不属于该主题!

标签: ruby-on-rails-3 mongodb mongoid


【解决方案1】:

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

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

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 文档中。

【讨论】:

    【解决方案2】:

    尝试使用 create 而不是 build。 EmbeddedDoc.build 和 EmbeddedDoc.new 不会触发任何保存回调(因为尚未保存任何内容),并且保存父文档不会调用嵌入的子回调(性能决定)。 EmbeddedDoc.create 应该触发嵌入式文档回调。

    my_content = Content.find(params[:id])
    puts my_content.localized_contents.create(params[:localized_content])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多