Как вы создаете ассоциации RoR Factory с accepts_nested_attributes_for?

StackOverflow https://stackoverflow.com/questions/1010532

Вопрос

Как отмечает Антон (спасибо Антону), моя проблема - кэширование ассоциаций в тестах, и похоже, что я правильно создал nested_attribute на фабрике. Правильный синтаксис:

Factory.define :job do |f|
  ...
  f.vehicles_attributes [{:vin => "1", :model => "ford", :make => "escort"},{:vin => "1", :model => "ford", :make => "escort" }]
end
<Ч>

Я использую accepts_nested__attributes_for в своей модели Job и пытаюсь перейти на заводскую девушку после того, как чуть не потерял свои шарики ". каждый раз, когда я меняю модель.

Я разместил кучу кода ниже, но мой вопрос прост:

Как использовать фабрики для создания nested_attributes?

Я могу создать экземпляр задания, используя приведенный ниже код, но не могу создать создание транспортных средств в своих модульных тестах. Без f.vehicles_attributes ... мои тесты задания не пройдут валидацию.

Мои модульные тесты дают следующие результаты:

  test "factory" do
    job = Factory(:job)
    assert(job.valid?)  # => true
    assert(job.vehicles.first.valid?) # => true
    vehicle = Factory(:vehicle)
    assert(vehicle.job.vehicles.size == 1) # => true
    assert_equal(vehicle.job.vehicles.first.vin, "2") # => FALSE.  <"1"> expected but was <"2">
  end
<Ч>
Factory.define :job do |f|
  ...
  f.vehicles_attributes [:vin => "1", :model => "ford", :make => "escort" ]
end

Factory.define :vehicle do |f|
  f.vin "2"
  f.model "ford"
  f.make "escort"
  f.association :job
end
<Ч>
class Job < ActiveRecord::Base
  has_many :vehicles, :dependent => :destroy
  validate :job_must_have_at_least_one_vehicle
  accepts_nested_attributes_for :vehicles, :allow_destroy => :true, :reject_if => proc { |vehicle_attributes| Job.insufficient_vehicle_input?(vehicle_attributes) }

  def job_must_have_at_least_one_vehicle
    errors.add(:vehicles, "need to be added") if self.vehicles.empty?
  end

  def self.insufficient_vehicle_input?(vehicle_attributes)
    vehicle_property_keys = vehicle_attributes.keys
    vehicle_property_keys.delete('_delete')
    vehicle_property_keys.delete('is_operational')
    vehicle_property_keys.delete('has_keys')
    vehicle_property_keys.each do |attribute_to_validate|
      if(!vehicle_attributes[attribute_to_validate].nil? && !vehicle_attributes[attribute_to_validate].empty?)
        return false
      end
    end
    return true
  end
end
Это было полезно?

Решение

Все дело в кэшировании ассоциаций .

Вот как это работает:
1. Factory (: vehicle) создает объект vehicle и создает запись job
2. После этого он заполняет vehicle.job_id и сохраняет его

Но vehicle.job указывает на объект job из шага 1.
Итак, все, что вам нужно, это перезагрузить job :

vehicle = Factory(:vehicle)
vehicle.job.reload.vehicles.size # => 2
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top