ar-simple-idmap 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -42,18 +42,36 @@ Then you should enable identity map for each model class individually:
42
42
  use_id_map
43
43
  belongs_to :tarif_plan
44
44
  end
45
+
46
+ You can use identity map for all models by writing in initializer:
47
+
48
+ class ActiveRecord::Base
49
+ use_id_map
50
+ end
45
51
 
46
52
  To enable in rake task or script:
47
53
 
48
- ActiveRecord.with_id_map do
54
+ ActiveRecord::Base.with_id_map do
49
55
  # all things here goes with identity map
50
56
  end
51
57
 
58
+ or equivalently
59
+
60
+ Client.with_id_map do
61
+ # all things here goes with identity map
62
+ # not only for Client
63
+ end
64
+
52
65
  If you found that identity logic does wrong thing in some particular place,
53
66
  you could temporary disable it:
54
67
 
55
- ActiveRecord.without_id_map do
68
+ ActiveRecord::Base.without_id_map do
69
+ # all things here goes without identity map
70
+ end
71
+
72
+ Client.without_id_map do
56
73
  # all things here goes without identity map
74
+ # not only for Client
57
75
  end
58
76
 
59
77
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.2.1
@@ -1,9 +1,9 @@
1
1
  module ActiveRecord
2
2
  class Base
3
- module IdentityMap
4
- module ClassMethods
5
- private
6
- def use_id_map
3
+ module IdentityMap
4
+ module ClassMethods
5
+ private
6
+ def use_id_map
7
7
  unless is_a? IdMapClassMethods
8
8
  extend IdMapClassMethods
9
9
  include IdMapInstanceMethods
@@ -14,21 +14,21 @@ module ActiveRecord
14
14
  alias_method_chain :create, :identity_map
15
15
  alias_method_chain :destroy, :identity_map
16
16
  end
17
- end
18
- end
19
-
20
- module IdMapClassMethods
17
+ end
18
+ end
19
+
20
+ module IdMapClassMethods
21
21
 
22
- def id_map
23
- thread_id_map.try(:for_class, self)
24
- end
25
-
26
- def if_id_map
27
- map = id_map
28
- yield map if map
29
- end
30
-
31
- private
22
+ def id_map
23
+ thread_id_map.try(:for_class, self)
24
+ end
25
+
26
+ def if_id_map
27
+ map = id_map
28
+ yield map if map
29
+ end
30
+
31
+ private
32
32
  def fetch_from_map(map, ids)
33
33
  result, not_cached = [], []
34
34
  ids.each do |id|
@@ -44,9 +44,9 @@ module ActiveRecord
44
44
  end
45
45
  result
46
46
  end
47
-
48
- def find_with_identity_map( *args )
49
- if_id_map do |map|
47
+
48
+ def find_with_identity_map( *args )
49
+ if_id_map do |map|
50
50
  from_arg0 = args.size == 1 ||
51
51
  args[1].is_a?(Hash) && !args[1].values.any?
52
52
  from_condition_ids = !from_arg0 &&
@@ -55,11 +55,11 @@ module ActiveRecord
55
55
  args[1].all?{|key, value| key == :conditions || value.blank?} &&
56
56
  args[1][:conditions].is_a?(Hash) &&
57
57
  args[1][:conditions].keys == [:id]
58
- if from_arg0 || from_condition_ids
59
- ids = from_arg0 ? args[0] : args[1][:conditions][:id]
60
- if ids.is_a?(Array)
58
+ if from_arg0 || from_condition_ids
59
+ ids = from_arg0 ? args[0] : args[1][:conditions][:id]
60
+ if ids.is_a?(Array)
61
61
  if from_arg0
62
- fetch_from_map( map, ids, &method(:find_without_identity_map) )
62
+ fetch_from_map( map, ids, &method(:find_without_identity_map) )
63
63
  elsif args[0] == :all
64
64
  fetch_from_map( map, ids ){|not_cached|
65
65
  find_without_identity_map(:all, {:conditions=>{:id=>not_cached}})
@@ -73,60 +73,60 @@ module ActiveRecord
73
73
  find_without_identity_map(:first, {:conditions=>{:id=>to_find}})
74
74
  end
75
75
  end
76
- else
77
- map[ids]
78
- end
79
- end
80
- end || find_without_identity_map(*args)
81
- end
82
-
83
- def instantiate_with_identity_map( record )
84
- if_id_map do |map|
85
- id = record[primary_key]
86
- if (object = map[id])
87
- attrs = object.instance_variable_get( :@attributes )
88
- unless (changed = object.instance_variable_get( :@changed_attributes )).blank?
89
- for key, value in record
90
- if changed.has_key? key
91
- changed[key] = value
92
- else
93
- attrs[key] = value
94
- end
95
- end
96
- else
97
- attrs.merge!( record ) unless attrs == record
98
- end
99
- object
100
- else
101
- map[id] = instantiate_without_identity_map( record )
102
- end
103
- end || instantiate_without_identity_map( record )
104
- end
105
-
106
- def delete_with_identity_map( ids )
107
- res = delete_without_identity_map( ids )
108
- if_id_map{|map| [ *ids ].each{|id| map.delete(id) } }
109
- res
110
- end
111
- end
112
-
113
- module IdMapInstanceMethods
114
- private
115
- def create_with_identity_map
116
- id = create_without_identity_map
117
- self.class.if_id_map{|map| map[id] = self }
118
- id
119
- end
120
-
121
- def destroy_with_identity_map
122
- res = destroy_without_identity_map
123
- self.class.if_id_map{|map| map.delete(id) }
124
- res
125
- end
126
- end
127
- end
128
-
129
- extend IdentityMap::ClassMethods
76
+ else
77
+ map[ids]
78
+ end
79
+ end
80
+ end || find_without_identity_map(*args)
81
+ end
82
+
83
+ def instantiate_with_identity_map( record )
84
+ if_id_map do |map|
85
+ id = record[primary_key]
86
+ if (object = map[id])
87
+ attrs = object.instance_variable_get( :@attributes )
88
+ unless (changed = object.instance_variable_get( :@changed_attributes )).blank?
89
+ for key, value in record
90
+ if changed.has_key? key
91
+ changed[key] = value
92
+ else
93
+ attrs[key] = value
94
+ end
95
+ end
96
+ else
97
+ attrs.merge!( record ) unless attrs == record
98
+ end
99
+ object
100
+ else
101
+ map[id] = instantiate_without_identity_map( record )
102
+ end
103
+ end || instantiate_without_identity_map( record )
104
+ end
105
+
106
+ def delete_with_identity_map( ids )
107
+ res = delete_without_identity_map( ids )
108
+ if_id_map{|map| [ *ids ].each{|id| map.delete(id) } }
109
+ res
110
+ end
111
+ end
112
+
113
+ module IdMapInstanceMethods
114
+ private
115
+ def create_with_identity_map
116
+ id = create_without_identity_map
117
+ self.class.if_id_map{|map| map[id] = self }
118
+ id
119
+ end
120
+
121
+ def destroy_with_identity_map
122
+ res = destroy_without_identity_map
123
+ self.class.if_id_map{|map| map.delete(id) }
124
+ res
125
+ end
126
+ end
127
+ end
128
+
129
+ extend IdentityMap::ClassMethods
130
130
  end
131
131
  end
132
132
 
@@ -52,6 +52,23 @@ describe "Customers" do
52
52
  c2.should be_nil
53
53
  end
54
54
 
55
+ it "should reload adequatly" do
56
+ Customer.connection.update_sql('update customers set value=2;')
57
+ @billy.reload
58
+ @billy.value.should == 2
59
+ end
60
+
61
+ it "should leave changed columns" do
62
+ @billy.value = 3
63
+ b = Customer.find_by_name("billy")
64
+ b.value.should == 3
65
+ b.value_changed?.should be_true
66
+ b.changes.should == {'value'=>[1,3]}
67
+ Customer.connection.update_sql('update customers set value=2;')
68
+ b = Customer.find_by_name("billy")
69
+ b.changes.should == {'value'=>[2,3]}
70
+ end
71
+
55
72
  after(:each) do
56
73
  @billy.destroy unless @billy.destroyed?
57
74
  end
data/spec/spec_helper.rb CHANGED
@@ -3,6 +3,10 @@ require 'spec'
3
3
  require 'active_support'
4
4
  require 'active_support/test_case'
5
5
  require 'active_record'
6
+ begin
7
+ require 'active_record/railtie'
8
+ rescue MissingSourceFile
9
+ end
6
10
  require 'active_record/test_case'
7
11
  require 'action_controller'
8
12
  require 'action_view'
@@ -19,6 +23,7 @@ ActiveRecord::Schema.define(:version => 0) do
19
23
  puts "Creating Schema"
20
24
  create_table :customers, :force => true do |t|
21
25
  t.string :name
26
+ t.integer :value, :default=>1
22
27
  end
23
28
  create_table :phone_numbers, :force => true do |t|
24
29
  t.string :number
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ar-simple-idmap
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 21
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 0
10
- version: 0.2.0
9
+ - 1
10
+ version: 0.2.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Sokolov Yura aka funny_falcon
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-03 00:00:00 +04:00
18
+ date: 2010-08-05 00:00:00 +04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -51,7 +51,6 @@ files:
51
51
  - lib/autotest/discover.rb
52
52
  - lib/identity_map.rb
53
53
  - lib/identity_map/action_controller/dispatcher.rb
54
- - lib/identity_map/active_record/associations.rb
55
54
  - lib/identity_map/active_record/base.rb
56
55
  - lib/identity_map/cache.rb
57
56
  - spec/identity_map_spec.rb
@@ -92,5 +91,5 @@ signing_key:
92
91
  specification_version: 3
93
92
  summary: Simple identity map for ActiveRecord
94
93
  test_files:
95
- - spec/identity_map_spec.rb
96
94
  - spec/spec_helper.rb
95
+ - spec/identity_map_spec.rb
@@ -1,31 +0,0 @@
1
- module IdentityMap
2
-
3
- def self.included(base)
4
- base.extend(ClassMethods)
5
- class << base
6
- alias_method_chain :association_instance_set, :identity_map
7
- end
8
- end
9
-
10
- module ClassMethods
11
-
12
- private
13
-
14
- # Set the specified association instance.
15
- def association_instance_set_with_identity_map(name, association)
16
- identity_map = Thread.current['identity_map']
17
- unless identity_map
18
- association_instance_set_without_identity_map("@#{name}", association)
19
- else
20
- association_instance_set_without_identity_map("@#{name}", identity_map.put(association))
21
- end
22
- end
23
-
24
-
25
- end
26
-
27
- end
28
-
29
- if Object.const_defined?("ActiveRecord")
30
- ActiveRecord::Associations.send :include, IdentityMap
31
- end