【问题标题】:Creating objects with Mongoid embedded many to one relationships使用 Mongoid 嵌入多对一关系创建对象
【发布时间】:2011-09-07 05:36:52
【问题描述】:

我正在尝试创建一个具有嵌入式属性的对象以进行测试。此示例使用具有多种语言的用户,但我希望为创建嵌入式对象的一般情况提供解决方案。

目前的创建代码:

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?

【问题讨论】:

    标签: ruby-on-rails-3 mongoid


    【解决方案1】:

    为了它的价值,我听从了@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)
    

    谢谢大家,案件结案。 ^^

    【讨论】:

      【解决方案2】:

      你真的应该使用 Fixtures,或者更好的 Factories。 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
      

      【讨论】:

      • FactoryGirl 似乎是正确的方法(它在我的“有时间时要学习的东西”列表中)。但是,我对此不太了解,并且您的代码出现错误。 ` NoMethodError: undefined method new?' for nil:NilClass 在“languages { [association(:language)] }” 行。
      • 呃哦,抱歉,factory_girl 似乎与 ActiveRecord 紧密耦合,因此您在使用 Mongoid 时可能会遇到问题。尽管如此,还有很多其他的rails工厂选择,例如fabricationgem.org。我自己没有使用它,但听到了很多积极的评价,它的页面上说 Fabrication 支持 Mongoid。
      • Fabricate 恰到好处。我很惊讶其他 mongoid 使用的应用程序没有被 factory_girl 发现。
      猜你喜欢
      • 1970-01-01
      • 2014-01-31
      • 1970-01-01
      • 2014-08-11
      • 2013-06-10
      • 2011-10-01
      • 2013-02-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多