Tuesday, September 27, 2011

Rails: The power of 'inverse_of'

There is a 'less known' feature of ActiveRecord associations that is very handy: the ability of marking an association as the mirror of another :inverse_of

The best is to rescue an example from the oficial documentation

class Dungeon < ActiveRecord::Base
  has_many :traps, :inverse_of => :dungeon
  has_one :evil_wizard, :inverse_of => :dungeon

class Trap < ActiveRecord::Base
  belongs_to :dungeon, :inverse_of => :traps

class EvilWizard < ActiveRecord::Base
  belongs_to :dungeon, :inverse_of => :evil_wizard
dungeon = Dungeon.first
wizard = dungeon.evil_wizard 

In a normal configuration, doing wizard.dungeon will hit the database and instantiate a new 'dungeon' (2 instances of the same object). 
With :inverse_of , Active record is aware of the relation and will use the same instance in memory. This has 2 benefits:
- we save a DB call
- as both 'dungeons' are the same instance, modifications on dungeon are seen from wizard (an the otehr way around)
Without :inverse_of , a modification on dungeon, is not seen by wizard.dungeon what can lead to subtle errors.
+1 for :inverse_of 


  1. What's the point of specifying inverse_of for "has_many <-> belongs_to" association? Aren't they ignored anyway?