Ale*_*lex 4 mongodb mongoid ruby-on-rails-3
我已经使用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
Run Code Online (Sandbox Code Playgroud)
这里没有什么真正复杂的,关于内容模型的行为一切正常,但是LocalizedContent模型的表现并不像我期望的那样,所以我的期望要么需要理顺,要么我需要帮助解决我做错的事情.
要创建新的嵌入式文档,请执行以下操作:
my_content = Content.find(params[:id])
my_content.localized_contents.build(params[:localized_content])
if parent.save
#redirect, etc.
end
Run Code Online (Sandbox Code Playgroud)
这是因为它在正确的内容中成功创建了一个新的嵌入式文档,但是我留下的时间戳字段为零
现在,如果我尝试更新那个localized_content:
my_content = Content.find(params[:content_id])
localized_content = my_content.localized_contents.find(params[:id])
Run Code Online (Sandbox Code Playgroud)
现在,如果我这样做: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.
Run Code Online (Sandbox Code Playgroud)
很公平,然后我原子地更新本地化内容上的字段并保存父级:
localized_content.fieldA = "value"
localized_content.fieldB = "value"
localized_content.fieldC = "value"
my_content.save
Run Code Online (Sandbox Code Playgroud)
这适用于正确更新本地化内容,但是: - timeteamps(udpated_at和created_at)仍然是nil - 版本没有收到当前localized_content的副本,并且版本不会增加!
因此,当我在这些小组和网络上的某些论坛上阅读很多场合时,出于性能原因,不会在嵌入式文档上触发回调,因为我在父级上调用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.
Run Code Online (Sandbox Code Playgroud)
更重要的是,我尝试在我的embedded: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.
Run Code Online (Sandbox Code Playgroud)
我疯了!请帮忙.我做错了什么?如何创建和更新嵌入式文档,以便我可以调用(甚至手动我不关心)正确的回调来更新时间戳和版本控制?
谢谢,
亚历克斯
ps:我使用的是rails 3.0.3和mongoid 2.0.1
tal*_*n55 13
为了防止这个答案对任何人都有用,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
Run Code Online (Sandbox Code Playgroud)
而已!现在,保存父对象将在子对象上运行回调(并且Mongoid::Timestamps足够智能,只能在实际更改的对象上运行).此信息位于嵌入式文档页面最底部的mongoid文档中.
| 归档时间: |
|
| 查看次数: |
3153 次 |
| 最近记录: |