Read more

Rails: When to use :inverse_of in has_many, has_one or belongs_to associations

Henning Koch
November 09, 2012Software engineer at makandra GmbH

When you have two models in a has_many, has_one or belongs_to association, the :inverse_of option in Rails tells ActiveRecord that they're two sides of the same association.

Illustration online protection

Rails Long Term Support

Rails LTS provides security patches for old versions of Ruby on Rails (2.3, 3.2, 4.2 and 5.2)

  • Prevents you from data breaches and liability risks
  • Upgrade at your own pace
  • Works with modern Rubies
Read more Show archive.org snapshot

Example with a has_many / belongs_to association:

class Forum < ActiveRecord::Base
  has_many :posts, inverse_of: :forum
end

class Post < ActiveRecord::Base
  belongs_to :forum, inverse_of: :posts
end

Knowing the other side of the same association Rails can optimize object loading so forum and forum.posts[0].forum will reference the same object in memory, instead of loading another copy of the same record.

Please read this great section about bi-directional associations Show archive.org snapshot from the Rails API for details.

Rails >= 4

Starting from Rails 4 the inverse_of is tried to be determined automatically, but it has some caveats and doesn't work in all cases.

If you don't want to know the details, just set :inverse_of in all cases.

If you want to minimize your code, always set inverse of if you use any option.

You can find out if the inverse_of is set correctly:

Forum.reflect_on_association(:posts).has_inverse? # => false  # missing and needs to be set manually
Forum.reflect_on_association(:posts).has_inverse? # => :forum # looks good

Below there are some known options where a automatically determination of the inverse is not working:

Rails < 4

You should always use the :inverse_of option in Rails < 4.

Posted by Henning Koch to makandra dev (2012-11-09 11:56)