我有两个模型,博客和主题。博客embeds_many:主题和主题embedded_in:博客。我还有Blog embeds_one:theme(用于激活的主题)。这不起作用。使用blog.themes.create
创建主题时,不会存储该主题。如果我改变了集合,那么它们就不会被嵌入,一切正常。
# This does NOT work!
class Blog
embeds_many :themes
embeds_one :theme
end
class Theme
embedded_in :blog
end
BUT
# This DOES work!
class Blog
has_many :themes
has_one :theme
end
class Theme
belongs_to :blog
end
任何人都知道这是为什么?
将主题之一分配给(选定)主题也存在问题。
blog.themes = [theme_1, theme_2]
blog.save!
blog.theme = blog.themes.first
blog.save!
blog.reload
blog.theme # returns nil
答案 0 :(得分:2)
通过这种方法,您可以将相同的文档嵌入两次:一次在主题集合中,然后在选定的主题中。
我建议删除第二个关系并使用字符串属性来存储当前主题名称。你可以这样做:
class Blog
include Mongoid::Document
field :current_theme_name, type: String
embeds_many :themes
def current_theme
themes.find_by(name: current_theme_name)
end
end
class Theme
include Mongoid::Document
field :name, type: String
embedded_in :blog
end
请注意,mongoid embeded文档在主文档的同时进行初始化,并且不需要额外的查询。
答案 1 :(得分:1)
好的,所以我遇到了同样的问题,并认为我偶然发现了解决方案(我正在检查code for the Metadata on relations)。
试试这个:
class Blog
embeds_many :themes, :as => :themes_collection, :class_name => "Theme"
embeds_one :theme, :as => :theme_item, :class_name => "Theme"
end
class Theme
embedded_in :themes_collection, :polymorphic => true
embedded_in :theme_item, :polymorphic => true
end
我所拥有的辨别猜测:
:themes
)实际上成为方法名称。:as
伪造了实际的关系,因此需要在两个类中匹配。:class_name
似乎非常明显,该类用于实际序列化数据。希望这会有所帮助 - 我显然不是关于mongoid内部工作的专家,但这应该足以让你跑步。我的测试现在是绿色的,数据按预期顺序排列。
答案 2 :(得分:1)
删除embeds_one :theme
,然后将其getter和setter方法放在Blog
类中:
def theme
themes.where(active: true).first
end
def theme=(thm)
theme.set(active: false)
thm.set(active: true)
end
blog.save!
之后无需调用blog.theme = blog.themes.first
因为set
执行原子操作。
此外,请不要忘记在field :active, type: Boolean, default: false
模型中添加Theme
。
希望这适合你。