2011-09-07 106 views
1

我试图创建一个嵌入属性的对象进行测试。这个例子使用多种语言的用户,但我很喜欢解决方案来创建嵌入对象的一般情况。使用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?

回答

2

你应该真的使用灯具,或更好的工厂。 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 
+0

FactoryGirl似乎是正确的做法(这是我获得时间的事情要了解的事情)。但是,我不太了解它,并且在代码中出现错误。 'NoMethodError: undefined method'new?' for nil:NilClass ' 在“languages {[association(:language)]}”行上。 – Tsagadai

+0

恩,哦,对不起,似乎factory_girl与ActiveRecord紧密结合,所以你可能在使用Mongoid时遇到问题。尽管如此,还有很多其他钢轨工厂的选择,例如http://fabricationgem.org/。我自己并没有使用它,但听到了很多正面评论,并且它在Fabrication支持Mongoid的页面上说道。 – binarycode

+0

制造是现货。我惊讶于其他的mongoid使用不会被factory_girl抓到的应用程序。 – Tsagadai

3

对于它的价值,我也跟着@ 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) 

感谢所有,结案。 ^^