Wie erstellen Sie RoR Werksverbände mit accepts_nested_attributes_for?
-
06-07-2019 - |
Frage
Wie Anton weist darauf hin (Danke Anton!) Mein Problem ist Verband Caching in den Tests und es scheint, wie ich richtig die nested_attribute in der Fabrik erstellt haben. Die korrekte Syntax lautet:
Factory.define :job do |f|
...
f.vehicles_attributes [{:vin => "1", :model => "ford", :make => "escort"},{:vin => "1", :model => "ford", :make => "escort" }]
end
Ich bin mit accepts_nested__attributes_for
in meinem Job-Modell und ich versuche, nach fast ins Werk Mädchen zu wandern meine Murmeln „Befestigung Tauchen“ jedes Mal, wenn ich das Modell ändern zu verlieren.
Ich schrieb einen Haufen Code unten, aber meine Frage ist einfach:
Wie kann ich Fabriken verwenden nested_attributes zu erstellen?
Ich bin die Lage, eine Job-Instanz mit dem nachfolgenden Code zu erstellen, aber ich kann in meinen Unit-Tests nicht schaffen schaffen Fahrzeuge. Ohne die f.vehicles_attributes...
nicht mein Job Test Validierungen.
Meine Unit-Tests erzeugen die folgenden Ergebnisse:
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
Lösung
Es geht um Assoziation Caching .
Hier ist, wie es funktioniert:
1. Factory(:vehicle)
baut vehicle
Objekt und schafft job
Rekord
2. Danach ist es füllt vehicle.job_id
und speichert sie
Aber vehicle.job
ist ein job
Objekt aus Schritt 1
weist darauf hin,
Also alles, was Sie brauchen, ist job
neu zu laden:
vehicle = Factory(:vehicle)
vehicle.job.reload.vehicles.size # => 2