我试图创建一个具有嵌入属性的对象进行测试。此示例使用具有多种语言的用户,但我希望能够为创建嵌入对象的一般情况提供解决方案。
展示创作代码:
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/complex-form-examples)。我不知道这是否正确,但我是这么认为的。
我可以看到一些明显的解决方案。一种是对输入进行硬编码,就像从表单生成的那样:
{"user"=>{ "languages_attributes"=>{"0"=>{"language"=>"en-US", "proficiency"=>"1", "_destroy"=>"false", "id"=>"en-dash-us"}}}
从长远来看,对我来说,这看起来并不干净。
另一个解决方案是剪切嵌入的对象并使用数组。 Mongoid非常擅长支持数组,但是你失去了为每个对象编写验证的能力,而且代码的可重用性也会降低。
想法,Stackoverflowers?
答案 0 :(得分:3)
为了它的价值,我遵循@cug的建议并使用了Fabrication。我在这里发布我的代码是为了帮助其他人解决这个问题。
spec / user / fabricator.rb Fabricator
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)
谢谢大家,案件已经结案。 ^^
答案 1 :(得分:2)
你应该真的使用Fixtures,或者更好的工厂。 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