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.

 
0
Kudos
 
0
Kudos

Now read this

How to fix `React DevTools encountered an error: RangeError: Invalid array length`

I recently found this rather obscure message in my dev tools console when working on a React + Gatsby based website. It took a bit of digging to figure out where it was coming from since the stack trace was all React internals. Turns out... Continue →