Exploring the :inverse_of option on rails model association

 Let's start with the basic models and defining inverse of relationship in these models:

class Criminal < ActiveRecord::Base
  belongs_to :prison, inverse_of: :criminals
end
class Prison < ActiveRecord::Base
  has_many :criminals, inverse_of: :prison
end 

Memory Optimization When Fetching Associated Records

It turns out that associated objects do not point to the same in-memory objects by default. To illustrate:

prison   = Prison.create(name: 'Bad House')
criminal = prison.criminals.create(name: 'Krazy 8')
 

# Without :inverse_of
criminal.prison == prison
# Prison Load (0.1ms)  SELECT "prisons".* FROM "prisons" WHERE "prisons"."id" = 2 LIMIT 1 # => true
 

# With :inverse_of
criminal.prison == prison
# => true

When we call criminal.prison without :inverse_of on both the :belongs_to and :has_many associations, it will hit the database. With :inverse_of, if we already have that prison record in memory then criminal.prison will point to the same prison.
It's worth clarifying that this only saves you a database look-up when going from Criminal to Prison (:belongs_to direction). Here's some console output going from the other direction:

prison = Prison.last

# Prison Load (0.1ms)  SELECT "prisons".* FROM "prisons" ORDER BY "prisons"."id" DESC LIMIT 1 # => #<Prison id: 3, name: "Broadmoor", created_at: "2014-10-10 20:26:38", updated_at: "2014-10-10 20:26:38">
 

criminal = prison.criminals.first
 

# Criminal Load (0.3ms)  SELECT "criminals".* FROM "criminals" WHERE "criminals"."prison_id" = 3 LIMIT 1 # => #<Criminal id: 3, name: "Charles Bronson", prison_id: 3, created_at: "2014-10-10 20:26:47", updated_at: "2014-10-10 20:26:47">
 

prison.criminals.first == criminal

# Criminal Load (0.2ms)  SELECT "criminals".* FROM "criminals" WHERE "criminals"."prison_id" = 3 LIMIT 1 # => true


A model's associations, as far as memory is concerned, are one-way bindings. The :inverse_of option basically gives us two-way memory bindings when one of the associations is a :belongs_to. A memory optimization isn't the only thing that :inverse_of gets you.









Comments

Popular posts from this blog

Installing Wowza Streaming Engine on ubuntu

Highcharts with grouped categories

Completely Uninstall and Install Rubymine on ubuntu