Создание объектов с Mongoid встраивает отношения один к одному - PullRequest
1 голос
/ 07 сентября 2011

Я пытаюсь создать объект со встроенными атрибутами для тестирования.В этом примере используется пользователь с несколькими языками, но мне хотелось бы найти решение для общего случая создания встроенных объектов.

Текущий код создания:

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

Эти модели прекрасно работают для создания объектов из вложенных форм по стопам Райана Бейтса (https://github.com/ryanb/complex-form-examples). Я не знаю, верный ли это путь, но я так предполагаю.

Есть несколькоочевидные решения, которые я вижу. Один из них - просто жестко закодировать ввод, как то, что генерируется из форм:

{"user"=>{ "languages_attributes"=>{"0"=>{"language"=>"en-US", "proficiency"=>"1", "_destroy"=>"false", "id"=>"en-dash-us"}}}

Мне это не кажется СУХИМЫМ или нормальным в долгосрочной перспективе.1016 * Другое решение - просто вырезать встроенные объекты и использовать массивы. Mongoid довольно хорошо поддерживает массивы, но вы теряете возможность писать проверки для каждого объекта, и код будет менее пригоден для повторного использования.

Мысли,Stackoverflowers

Ответы [ 2 ]

3 голосов
/ 08 сентября 2011

Для чего бы это ни стоило, я последовал совету @ cug и использовал Fabrication. Я публикую здесь свой код для тех, кто столкнулся с этой проблемой.

Спецификация / пользователь / 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 голосов
/ 07 сентября 2011

Вы должны действительно использовать приспособления, или лучшие фабрики для этого. 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
...