使用Mongoid嵌入多对一关系创建对象
问题描述:
我试图创建一个嵌入属性的对象进行测试。这个例子使用多种语言的用户,但我很喜欢解决方案来创建嵌入对象的一般情况。使用Mongoid嵌入多对一关系创建对象
目前创建代码:
def valid_attributes
{ :languages => [Language.new(language: "en-US", proficiency: "1")] }
end
user = User.create! valid_attributes
的车型:
class User
include Mongoid::Document
field :languages
embeds_many :languages
validates_presence_of :languages
attr_accessible :languages_attributes
accepts_nested_attributes_for :languages, :reject_if => lambda { |a| a[:language].blank? }, :allow_destroy => true
end
class Language
include Mongoid::Document
field :language
field :proficiency
key :language
embedded_in :user
attr_accessible :language, :proficiency
end
这些模型做工精细在Ryan Bates的脚步声从创建嵌套表格对象(https://github.com/ryanb /复杂外形的例子)。我不知道这是否正确,但我是这么认为的。
我可以看到一些明显的解决方案。一个是刚刚硬编码等从形式生成的内容输入:
{"user"=>{ "languages_attributes"=>{"0"=>{"language"=>"en-US", "proficiency"=>"1", "_destroy"=>"false", "id"=>"en-dash-us"}}}
似乎并不干的,或理智,从长远来看,对我来说。
另一种解决方案是只剪切嵌入的对象并使用数组。 Mongoid在支持数组方面非常出色,但是你失去了为每个对象编写验证的能力,并且代码的可重用性会降低。
想法,Stackoverflowers?
答
你应该真的使用灯具,或更好的工厂。 FactoryGirl非常受欢迎 创建工厂。
你的情况,你将不得不在spec/factories.rb
定义工厂这样的:
FactoryGirl.define do
factory :user do
languages { [association(:language)] }
end
factory :language do
language "en-US"
proficiency "1"
end
end
而不是用它在你的测试一样,
user = FactoryGirl.create :user
答
对于它的价值,我也跟着@ cug的建议和使用制造。我在这里发布我的代码是为了解决这个问题的其他人的利益。
的投机/用户/ fabricator.rb加工厂
Fabricator(:language) do
language "en-US"
proficiency "1"
end
Fabricator(:user) do
languages { [ Fabricate.build(:language, :language => "en-US", :proficiency => "1") ] }
end
创建这样一个用户:
user = Fabricate.build(:user)
感谢所有,结案。 ^^
FactoryGirl似乎是正确的做法(这是我获得时间的事情要了解的事情)。但是,我不太了解它,并且在代码中出现错误。 'NoMethodError: undefined method'new?' for nil:NilClass ' 在“languages {[association(:language)]}”行上。 – Tsagadai
恩,哦,对不起,似乎factory_girl与ActiveRecord紧密结合,所以你可能在使用Mongoid时遇到问题。尽管如此,还有很多其他钢轨工厂的选择,例如http://fabricationgem.org/。我自己并没有使用它,但听到了很多正面评论,并且它在Fabrication支持Mongoid的页面上说道。 – binarycode
制造是现货。我惊讶于其他的mongoid使用不会被factory_girl抓到的应用程序。 – Tsagadai