Question

Comme Anton le fait remarquer (merci Anton!), mon problème est l’association Caching dans les tests et il semble que j’ai correctement créé l’attribut nested_attribute dans l’usine. La syntaxe correcte est la suivante:

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

J'utilise includes_nested__attributes_for dans mon modèle Job et j'essaie de migrer vers Factory Girl après avoir failli perdre mes billes. chaque fois que je change de modèle.

J'ai posté un tas de code ci-dessous mais ma question est simple:

Comment utiliser les usines pour créer des attributs imbriqués?

Je peux créer une instance de tâche à l'aide du code ci-dessous, mais je ne peux pas créer de véhicules dans mes tests unitaires. Sans f.vehicles_attributes ... , la validation des tests de mon travail échoue.

Mes tests unitaires produisent les résultats suivants:

  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
Était-ce utile?

La solution

Tout est question de mise en cache des associations .

Voici comment cela fonctionne:
1. Usine (: véhicule) crée un objet véhicule et crée un enregistrement travail

2. Après cela, il remplit vehicle.job_job et le sauvegarde

.

Mais vehicle.job indique un objet travail à l'étape 1.
Donc, tout ce dont vous avez besoin est de recharger travail :

vehicle = Factory(:vehicle)
vehicle.job.reload.vehicles.size # => 2
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top