Suppose you are creating a record which holds a Sauce and percentages or ingredients that must add up to 100%. You have the parent record, the
Sauce and the children
Tips on Using Factory Girl to Create a Record with Mandatory Children
This article has the right format which is not what you’d expect
FactoryGirl.define do factory :recipe do name 'Secret Sauce' after_build do |sauce| sauce << FactoryGirl.build(:sauce_component, percentage: 0.60, sauce: sauce) sauce << FactoryGirl.build(:sauce_component, percentage: 0.40, sauce: sauce) end end end
- The use of the
- The inclusion of the
FactoryGirl.buildeven though we’re using
- The use of
Validate presence of the belongs_to foreign key with the object, not the id
Use the association not the association_id when doing validations for presence in Rails! Otherwise, the validator complains the id doesn’t exist, and you can’t get FactoryGirl to save the parent record.
Thus, the right validation in the SauceComponent model is
validates :sauce, presence: true
This one prevents the FactoryGirl syntax from running, because the sauce_id is nil at first, so the records don’t save. Don’t do this one!
validates :sauce_id, presence: true
And it’s SUPER important to specify the
belongs_to using the
Otherwise, you’ll have issues with validating for the presence of the
Sauce in the
SauceComponent because they get created at the same time.
Accepts Nested Attributes
This article is helpful:
When displaying 2 levels of nesting, it’s incredibly important to check for
sauce_component.object.marked_for_destruction? when looping through the child records:
= f.simple_fields_for :sauce_components do |sauce_component| - unless sauce_component.object.marked_for_destruction? = render 'sauce_component_fields', :f => sauce_component
Otherwise, if you get a validation error, you’ll display the record that you deleted, which is very confusing!