Files

Class Index [+]

Quicksearch

ActiveRecord::IdentityMap

Active Record Identity Map

Ensures that each object gets loaded only once by keeping every loaded object in a map. Looks up objects using the map when referring to them.

More information on Identity Map pattern:

  http://www.martinfowler.com/eaaCatalog/identityMap.html

Configuration

In order to enable IdentityMap, set config.active_record.identity_map = true in your config/application.rb file.

IdentityMap is disabled by default and still in development (i.e. use it with care).

Associations

Active Record Identity Map does not track associations yet. For example:

  comment = @post.comments.first
  comment.post = nil
  @post.comments.include?(comment) #=> true

Ideally, the example above would return false, removing the comment object from the post association when the association is nullified. This may cause side effects, as in the situation below, if Identity Map is enabled:

  Post.has_many :comments, :dependent => :destroy

  comment = @post.comments.first
  comment.post = nil
  comment.save
  Post.destroy(@post.id)

Without using Identity Map, the code above will destroy the @post object leaving the comment object intact. However, once we enable Identity Map, the post loaded by Post.destroy is exactly the same object as the object @post. As the object @post still has the comment object in @post.comments, once Identity Map is enabled, the comment object will be accidently removed.

This inconsistency is meant to be fixed in future Rails releases.

Public Class Methods

add(record) click to toggle source
    # File lib/active_record/identity_map.rb, line 92
92:       def add(record)
93:         repository[record.class.symbolized_sti_name][record.id] = record if contain_all_columns?(record)
94:       end
clear() click to toggle source
     # File lib/active_record/identity_map.rb, line 104
104:       def clear
105:         repository.clear
106:       end
enabled() click to toggle source
    # File lib/active_record/identity_map.rb, line 51
51:       def enabled
52:         Thread.current[:identity_map_enabled]
53:       end
enabled=(flag) click to toggle source
    # File lib/active_record/identity_map.rb, line 47
47:       def enabled=(flag)
48:         Thread.current[:identity_map_enabled] = flag
49:       end
get(klass, primary_key) click to toggle source
    # File lib/active_record/identity_map.rb, line 77
77:       def get(klass, primary_key)
78:         record = repository[klass.symbolized_sti_name][primary_key]
79: 
80:         if record.is_a?(klass)
81:           ActiveSupport::Notifications.instrument("identity.active_record",
82:             :line => "From Identity Map (id: #{primary_key})",
83:             :name => "#{klass} Loaded",
84:             :connection_id => object_id)
85: 
86:           record
87:         else
88:           nil
89:         end
90:       end
remove(record) click to toggle source
    # File lib/active_record/identity_map.rb, line 96
96:       def remove(record)
97:         repository[record.class.symbolized_sti_name].delete(record.id)
98:       end
remove_by_id(symbolized_sti_name, id) click to toggle source
     # File lib/active_record/identity_map.rb, line 100
100:       def remove_by_id(symbolized_sti_name, id)
101:         repository[symbolized_sti_name].delete(id)
102:       end
repository() click to toggle source
    # File lib/active_record/identity_map.rb, line 56
56:       def repository
57:         Thread.current[:identity_map] ||= Hash.new { |h,k| h[k] = {} }
58:       end
use() click to toggle source
    # File lib/active_record/identity_map.rb, line 60
60:       def use
61:         old, self.enabled = enabled, true
62: 
63:         yield if block_given?
64:       ensure
65:         self.enabled = old
66:         clear
67:       end
without() click to toggle source
    # File lib/active_record/identity_map.rb, line 69
69:       def without
70:         old, self.enabled = enabled, false
71: 
72:         yield if block_given?
73:       ensure
74:         self.enabled = old
75:       end

Private Class Methods

contain_all_columns?(record) click to toggle source
     # File lib/active_record/identity_map.rb, line 110
110:         def contain_all_columns?(record)
111:           (record.class.column_names - record.attribute_names).empty?
112:         end

Public Instance Methods

reinit_with(coder) click to toggle source

Reinitialize an Identity Map model object from coder. coder must contain the attributes necessary for initializing an empty model object.

     # File lib/active_record/identity_map.rb, line 118
118:     def reinit_with(coder)
119:       @attributes_cache = {}
120:       dirty      = @changed_attributes.keys
121:       attributes = self.class.initialize_attributes(coder['attributes'].except(*dirty))
122:       @attributes.update(attributes)
123:       @changed_attributes.update(coder['attributes'].slice(*dirty))
124:       @changed_attributes.delete_if{|k,v| v.eql? @attributes[k]}
125: 
126:       run_callbacks :find
127: 
128:       self
129:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.