Directly from ActiveRecord documentation on bi-directional associations:
Bi-directional associations
When you specify an association there is usually an association on the associated model that specifies the same relationship in reverse. For example, with the following models:
class Dungeon < ActiveRecord::Base has_many :traps has_one :evil_wizard end class Trap < ActiveRecord::Base belongs_to :dungeon end class EvilWizard < ActiveRecord::Base belongs_to :dungeon end
The traps association on Dungeon and the dungeon association on Trap are the inverse of each other and the inverse of the dungeon association on EvilWizard is the evil_wizard association on Dungeon (and vice-versa). By default, Active Record doesn’t know anything about these inverse relationships and so no object loading optimization is possible. For example:
d = Dungeon.first t = d.traps.first d.level == t.dungeon.level # => true d.level = 10 d.level == t.dungeon.level # => false
The Dungeon instances
d
andt.dungeon
in the above example refer to the same object data from the database, but are actually different in-memory copies of that data. **Specifying the:inverse_of
option on associations lets you tell Active Record about inverse relationships and it will optimise object loading. For example, if we changed our model definitions to:class Dungeon < ActiveRecord::Base has_many :traps, inverse_of: :dungeon has_one :evil_wizard, inverse_of: :dungeon end class Trap < ActiveRecord::Base belongs_to :dungeon, inverse_of: :traps end class EvilWizard < ActiveRecord::Base belongs_to :dungeon, inverse_of: :evil_wizard end
Then, from our code snippet above,
d
andt.dungeon
are actually the same in-memory instance and our finald.level == t.dungeon.level
will return true.There are limitations to
:inverse_of
support:
- does not work with
:through
associations.- does not work with
:polymorphic
associations.- for
belongs_to
associationshas_many
inverse associations are ignored.
Leave a Reply