Co-dependent Models in Rails
Sometimes you have a one-to-many relationship in your Rails models and you want to allow nested attributes at the time of creation. So you do this:
# Seems like it would work, but does NOT:
class User < ApplicationModel
has_many :tags
accepts_nested_attributes_for :tags
end
class Tag < ApplicationModel
belongs_to :user
end
When you try to save a user, though, you run into trouble: ActiveRecord tries to validate autosaved nested records, and those nested records have an implicit required: true
validation on the parent model which, in this case, doesn’t have an ID yet.
The fix is simple, but unintuitive: manually specify the inverse_of
option on the association. ActiveRecord can create a bidirectional association automatically, but in this particular case, it doesn’t work.
# Redundant, but works
class User < ApplicationModel
has_many :tags, inverse_of: :user
accepts_nested_attributes_for :tags
end
class Tag < ApplicationModel
belongs_to :user, inverse_of: :tags
end
This will give ActiveRecord the information it needs to allow the “required” validation on the belongs_to
to verify the associated model is in place even though it doesn’t have an ID, allowing your models to save as expected.