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.

 
1
Kudos
 
1
Kudos

Now read this

Using Webster’s 1913 Dictionary on macOS Catalina, Big Sur, or Monterey

I recently had the pleasure of discovering James Somer’s blog through Instapaper’s weekly “top highlights” email. I found James’ post about the dictionary particularly compelling, and it seems I’m not alone. Alas, the instructions... Continue →