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

Typo Forgiveness in Git &amp; Bash

I’m often moving pretty quickly when it comes time to commit work to Git. I have a bit of a workflow down, and I type the same few shortcuts frequently: $ git st (expands to status) $ git ks (expands to difftool, which opens... Continue →