An action creates records based on multiple layers of nested attributes, upon the submission of a form. However, the ID of the root record, which I call .save
on, is not propagating downwards to the associations.
Here's a simplified example:
class A
has_many :bs
# Note that A has direct access to C, without going through B
has_many :cs
accepts_nested_attributes_for :b
end
class B
# B has an :a_id field
belongs_to :a
has_many :cs
accepts_nested_attributes_for :c
end
class C
# note that C has a "circular relationship" to A,
# either directly through the :a_id field, or indirectly through B
belongs_to :a
belongs_to :b
end
Given the model definitions above, this is an example payload:
{
a: {
name: "Model A",
bs_attributes: [{
name: "Model B",
cs_attributes: [{
name: "Model C"
}]
}]
}
}
And this payload will be fed into:
A.create(payload)
When that gets persisted on the database and A is assigned an ID, I expect this ID to be automatically set as a foreign key on both children (B) and grand-children (C) records. Is that something that can be accomplished using Rails built-in functions, with simple effort?
An example of solution I could think of would be adding a before_save callback on associations to manually set the :a_id
field. However this feels like it could be accomplished in simpler ways.
Currently working on Rails 5 but any guidance is appreciated.
Using inverse_of
to link the associations should work for the nested attributes. Example, A to B:
class A
has_many :bs, inverse_of: :a
accepts_nested_attributes_for :b
end
class B
belongs_to :a, inverse_of: :bs
end
Same thing for C to B.
A to C is a bit special.
Setting c.a = b.a
in before_validation
callback on C is an option.