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
end

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

class EvilWizard < ActiveRecord::Base
  belongs_to :dungeon, :inverse_of => :evil_wizard
end
 
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 
 
 

3 comments:

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

    ReplyDelete