inverse_of 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,8 @@
1
+ == 0.1.0 2011-08-31
2
+
3
+ * Fix bug with eager loading.
4
+ * Require AR < 2.3.6.
5
+
6
+ == 0.0.1 2010-02-05
7
+
8
+ * Hi.
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009 George Ogata
1
+ Copyright (c) 2009-2010 George Ogata
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/Rakefile CHANGED
@@ -1,38 +1 @@
1
- require 'rubygems'
2
- require 'rake'
3
-
4
- begin
5
- require 'jeweler'
6
- Jeweler::Tasks.new do |gem|
7
- gem.name = "inverse_of"
8
- gem.summary = "Backport of ActiveRecord 2.3.6's inverse associations."
9
- gem.description = "Backport of ActiveRecord 2.3.6's inverse associations."
10
- gem.email = "george.ogata@gmail.com"
11
- gem.homepage = "http://github.com/oggy/inverse_of"
12
- gem.authors = ["George Ogata"]
13
- end
14
- Jeweler::GemcutterTasks.new
15
- rescue LoadError
16
- puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
17
- end
18
-
19
- require 'rake/testtask'
20
-
21
- desc "Run the test/unit tests for inverse associations, backported from ActiveRecord 2.3.6."
22
- Rake::TestTask.new(:test => :check_dependencies) do |test|
23
- test.libs << 'lib' << 'test'
24
- test.pattern = 'test/**/*_test.rb'
25
- test.verbose = true
26
- end
27
-
28
- task :default => :test
29
-
30
- require 'rake/rdoctask'
31
- Rake::RDocTask.new do |rdoc|
32
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
33
-
34
- rdoc.rdoc_dir = 'rdoc'
35
- rdoc.title = "inverse_of #{version}"
36
- rdoc.rdoc_files.include('README*')
37
- rdoc.rdoc_files.include('lib/**/*.rb')
38
- end
1
+ require 'ritual'
@@ -1,293 +1,292 @@
1
- if ([ActiveRecord::VERSION::MAJOR, ActiveRecord::VERSION::MINOR, ActiveRecord::VERSION::TINY] <=> [2, 3, 6]) < 0
2
- module InverseOf
3
- class InverseOfAssociationNotFoundError < ActiveRecord::ActiveRecordError #:nodoc:
4
- def initialize(reflection, associated_class = nil)
5
- super("Could not find the inverse association for #{reflection.name} (#{reflection.options[:inverse_of].inspect} in #{associated_class.nil? ? reflection.class_name : associated_class.name})")
6
- end
1
+ module InverseOf
2
+ class InverseOfAssociationNotFoundError < ActiveRecord::ActiveRecordError #:nodoc:
3
+ def initialize(reflection, associated_class = nil)
4
+ super("Could not find the inverse association for #{reflection.name} (#{reflection.options[:inverse_of].inspect} in #{associated_class.nil? ? reflection.class_name : associated_class.name})")
5
+ end
6
+ end
7
+
8
+ module Reflection
9
+ def self.included(base)
10
+ base::AssociationReflection.send :include, AssociationReflection
11
+ base::ThroughReflection.send :include, ThroughReflection
7
12
  end
8
13
 
9
- module Reflection
14
+ module AssociationReflection
10
15
  def self.included(base)
11
- base::AssociationReflection.send :include, AssociationReflection
12
- base::ThroughReflection.send :include, ThroughReflection
16
+ base.alias_method_chain :check_validity!, :inverse_of
13
17
  end
14
18
 
15
- module AssociationReflection
16
- def self.included(base)
17
- base.alias_method_chain :check_validity!, :inverse_of
18
- end
19
-
20
- def check_validity_with_inverse_of!
21
- check_validity_of_inverse!
22
- check_validity_without_inverse_of!
23
- end
19
+ def check_validity_with_inverse_of!
20
+ check_validity_of_inverse!
21
+ check_validity_without_inverse_of!
22
+ end
24
23
 
25
- def check_validity_of_inverse!
26
- unless options[:polymorphic]
27
- if has_inverse? && inverse_of.nil?
28
- raise InverseOfAssociationNotFoundError.new(self)
29
- end
24
+ def check_validity_of_inverse!
25
+ unless options[:polymorphic]
26
+ if has_inverse? && inverse_of.nil?
27
+ raise InverseOfAssociationNotFoundError.new(self)
30
28
  end
31
29
  end
30
+ end
32
31
 
33
- def has_inverse?
34
- !@options[:inverse_of].nil?
35
- end
32
+ def has_inverse?
33
+ !@options[:inverse_of].nil?
34
+ end
36
35
 
37
- def inverse_of
38
- if has_inverse?
39
- @inverse_of ||= klass.reflect_on_association(options[:inverse_of])
40
- end
36
+ def inverse_of
37
+ if has_inverse?
38
+ @inverse_of ||= klass.reflect_on_association(options[:inverse_of])
41
39
  end
40
+ end
42
41
 
43
- def polymorphic_inverse_of(associated_class)
44
- if has_inverse?
45
- if inverse_relationship = associated_class.reflect_on_association(options[:inverse_of])
46
- inverse_relationship
47
- else
48
- raise InverseOfAssociationNotFoundError.new(self, associated_class)
49
- end
42
+ def polymorphic_inverse_of(associated_class)
43
+ if has_inverse?
44
+ if inverse_relationship = associated_class.reflect_on_association(options[:inverse_of])
45
+ inverse_relationship
46
+ else
47
+ raise InverseOfAssociationNotFoundError.new(self, associated_class)
50
48
  end
51
49
  end
52
50
  end
51
+ end
53
52
 
54
- module ThroughReflection
55
- def self.included(base)
56
- base.alias_method_chain :check_validity!, :inverse_of
57
- end
53
+ module ThroughReflection
54
+ def self.included(base)
55
+ base.alias_method_chain :check_validity!, :inverse_of
56
+ end
58
57
 
59
- def check_validity_with_inverse_of!
60
- check_validity_of_inverse!
61
- check_validity_without_inverse_of!
62
- end
58
+ def check_validity_with_inverse_of!
59
+ check_validity_of_inverse!
60
+ check_validity_without_inverse_of!
63
61
  end
64
62
  end
63
+ end
65
64
 
66
- module Associations
67
- module AssociationCollection
68
- def self.included(base)
69
- base.alias_method_chain :find_target, :inverse_of
70
- base.alias_method_chain :add_record_to_target_with_callbacks, :inverse_of
71
- end
72
-
73
- def find_target_with_inverse_of
74
- records = find_target_without_inverse_of
75
- records.each do |record|
76
- set_inverse_instance(record, @owner)
77
- end
78
- records
79
- end
65
+ module Associations
66
+ module AssociationCollection
67
+ def self.included(base)
68
+ base.alias_method_chain :find_target, :inverse_of
69
+ base.alias_method_chain :add_record_to_target_with_callbacks, :inverse_of
70
+ end
80
71
 
81
- def add_record_to_target_with_callbacks_with_inverse_of(record, &block)
82
- record = add_record_to_target_with_callbacks_without_inverse_of(record, &block)
72
+ def find_target_with_inverse_of
73
+ records = find_target_without_inverse_of
74
+ records.each do |record|
83
75
  set_inverse_instance(record, @owner)
84
- record
85
76
  end
77
+ records
86
78
  end
87
79
 
88
- module AssociationProxy
89
- def self.included(base)
90
- base.alias_method_chain :initialize, :inverse_of
91
- end
80
+ def add_record_to_target_with_callbacks_with_inverse_of(record, &block)
81
+ record = add_record_to_target_with_callbacks_without_inverse_of(record, &block)
82
+ set_inverse_instance(record, @owner)
83
+ record
84
+ end
85
+ end
92
86
 
93
- def initialize_with_inverse_of(owner, reflection)
94
- reflection.check_validity!
95
- initialize_without_inverse_of(owner, reflection)
96
- end
87
+ module AssociationProxy
88
+ def self.included(base)
89
+ base.alias_method_chain :initialize, :inverse_of
90
+ end
97
91
 
98
- private
92
+ def initialize_with_inverse_of(owner, reflection)
93
+ reflection.check_validity!
94
+ initialize_without_inverse_of(owner, reflection)
95
+ end
99
96
 
100
- def set_inverse_instance(record, instance)
101
- return if record.nil? || !we_can_set_the_inverse_on_this?(record)
102
- inverse_relationship = @reflection.inverse_of
103
- unless inverse_relationship.nil?
104
- record.send(:"set_#{inverse_relationship.name}_target", instance)
105
- end
106
- end
97
+ private
107
98
 
108
- # Override in subclasses
109
- def we_can_set_the_inverse_on_this?(record)
110
- false
99
+ def set_inverse_instance(record, instance)
100
+ return if record.nil? || !we_can_set_the_inverse_on_this?(record)
101
+ inverse_relationship = @reflection.inverse_of
102
+ unless inverse_relationship.nil?
103
+ record.send(:"set_#{inverse_relationship.name}_target", instance)
111
104
  end
112
105
  end
113
106
 
114
- module BelongsToAssociation
115
- def self.included(base)
116
- base.alias_method_chain :replace, :inverse_of
117
- base.alias_method_chain :find_target, :inverse_of
118
- end
107
+ # Override in subclasses
108
+ def we_can_set_the_inverse_on_this?(record)
109
+ false
110
+ end
111
+ end
119
112
 
120
- def replace_with_inverse_of(record)
121
- replace_without_inverse_of(record)
122
- set_inverse_instance(record, @owner)
123
- record
124
- end
113
+ module BelongsToAssociation
114
+ def self.included(base)
115
+ base.alias_method_chain :replace, :inverse_of
116
+ base.alias_method_chain :find_target, :inverse_of
117
+ end
125
118
 
126
- def find_target_with_inverse_of
127
- target = find_target_without_inverse_of and
128
- set_inverse_instance(target, @owner)
129
- target
130
- end
119
+ def replace_with_inverse_of(record)
120
+ replace_without_inverse_of(record)
121
+ set_inverse_instance(record, @owner)
122
+ record
123
+ end
131
124
 
132
- # NOTE - for now, we're only supporting inverse setting from belongs_to back onto
133
- # has_one associations.
134
- def we_can_set_the_inverse_on_this?(record)
135
- @reflection.has_inverse? && @reflection.inverse_of.macro == :has_one
136
- end
125
+ def find_target_with_inverse_of
126
+ target = find_target_without_inverse_of and
127
+ set_inverse_instance(target, @owner)
128
+ target
137
129
  end
138
130
 
139
- module BelongsToPolymorphicAssociation
140
- def self.included(base)
141
- base.alias_method_chain :replace, :inverse_of
142
- base.alias_method_chain :find_target, :inverse_of
143
- end
131
+ # NOTE - for now, we're only supporting inverse setting from belongs_to back onto
132
+ # has_one associations.
133
+ def we_can_set_the_inverse_on_this?(record)
134
+ @reflection.has_inverse? && @reflection.inverse_of.macro == :has_one
135
+ end
136
+ end
144
137
 
145
- def replace_with_inverse_of(record)
146
- replace_without_inverse_of(record)
147
- set_inverse_instance(record, @owner)
148
- record
149
- end
138
+ module BelongsToPolymorphicAssociation
139
+ def self.included(base)
140
+ base.alias_method_chain :replace, :inverse_of
141
+ base.alias_method_chain :find_target, :inverse_of
142
+ end
150
143
 
151
- def find_target_with_inverse_of
152
- target = find_target_without_inverse_of
153
- set_inverse_instance(target, @owner)
154
- target
155
- end
144
+ def replace_with_inverse_of(record)
145
+ replace_without_inverse_of(record)
146
+ set_inverse_instance(record, @owner)
147
+ record
148
+ end
156
149
 
157
- # NOTE - for now, we're only supporting inverse setting from belongs_to back onto
158
- # has_one associations.
159
- def we_can_set_the_inverse_on_this?(record)
160
- if @reflection.has_inverse?
161
- inverse_association = @reflection.polymorphic_inverse_of(record.class)
162
- inverse_association && inverse_association.macro == :has_one
163
- else
164
- false
165
- end
166
- end
150
+ def find_target_with_inverse_of
151
+ target = find_target_without_inverse_of
152
+ set_inverse_instance(target, @owner)
153
+ target
154
+ end
167
155
 
168
- def set_inverse_instance(record, instance)
169
- return if record.nil? || !we_can_set_the_inverse_on_this?(record)
170
- inverse_relationship = @reflection.polymorphic_inverse_of(record.class)
171
- unless inverse_relationship.nil?
172
- record.send(:"set_#{inverse_relationship.name}_target", instance)
173
- end
156
+ # NOTE - for now, we're only supporting inverse setting from belongs_to back onto
157
+ # has_one associations.
158
+ def we_can_set_the_inverse_on_this?(record)
159
+ if @reflection.has_inverse?
160
+ inverse_association = @reflection.polymorphic_inverse_of(record.class)
161
+ inverse_association && inverse_association.macro == :has_one
162
+ else
163
+ false
174
164
  end
175
165
  end
176
166
 
177
- module HasManyAssociation
178
- def we_can_set_the_inverse_on_this?(record)
179
- inverse = @reflection.inverse_of
180
- return !inverse.nil?
167
+ def set_inverse_instance(record, instance)
168
+ return if record.nil? || !we_can_set_the_inverse_on_this?(record)
169
+ inverse_relationship = @reflection.polymorphic_inverse_of(record.class)
170
+ unless inverse_relationship.nil?
171
+ record.send(:"set_#{inverse_relationship.name}_target", instance)
181
172
  end
182
173
  end
174
+ end
183
175
 
184
- module HasManyThroughAssociation
185
- def initialize(owner, reflection)
186
- super
187
- end
176
+ module HasManyAssociation
177
+ def we_can_set_the_inverse_on_this?(record)
178
+ inverse = @reflection.inverse_of
179
+ return !inverse.nil?
180
+ end
181
+ end
188
182
 
189
- # NOTE - not sure that we can actually cope with inverses here
190
- def we_can_set_the_inverse_on_this?(record)
191
- false
192
- end
183
+ module HasManyThroughAssociation
184
+ def initialize(owner, reflection)
185
+ super
193
186
  end
194
187
 
195
- module HasOneAssociation
196
- def self.included(base)
197
- base.alias_method_chain :find_target, :inverse_of
198
- base.alias_method_chain :new_record, :inverse_of
199
- base.alias_method_chain :replace, :inverse_of
200
- end
188
+ # NOTE - not sure that we can actually cope with inverses here
189
+ def we_can_set_the_inverse_on_this?(record)
190
+ false
191
+ end
192
+ end
201
193
 
202
- def find_target_with_inverse_of
203
- target = find_target_without_inverse_of
204
- set_inverse_instance(target, @owner)
205
- target
206
- end
194
+ module HasOneAssociation
195
+ def self.included(base)
196
+ base.alias_method_chain :find_target, :inverse_of
197
+ base.alias_method_chain :new_record, :inverse_of
198
+ base.alias_method_chain :replace, :inverse_of
199
+ end
207
200
 
208
- def replace_with_inverse_of(record, dont_save = false)
209
- value = replace_without_inverse_of(record, dont_save)
210
- set_inverse_instance(record, @owner)
211
- value
212
- end
201
+ def find_target_with_inverse_of
202
+ target = find_target_without_inverse_of
203
+ set_inverse_instance(target, @owner)
204
+ target
205
+ end
213
206
 
214
- private
207
+ def replace_with_inverse_of(record, dont_save = false)
208
+ value = replace_without_inverse_of(record, dont_save)
209
+ set_inverse_instance(record, @owner)
210
+ value
211
+ end
215
212
 
216
- def new_record_with_inverse_of(replace_existing, &block)
217
- record = new_record_without_inverse_of(replace_existing, &block)
218
- set_inverse_instance(record, @owner) unless replace_existing
219
- record
220
- end
213
+ private
221
214
 
222
- def we_can_set_the_inverse_on_this?(record)
223
- inverse = @reflection.inverse_of
224
- return !inverse.nil?
225
- end
215
+ def new_record_with_inverse_of(replace_existing, &block)
216
+ record = new_record_without_inverse_of(replace_existing, &block)
217
+ set_inverse_instance(record, @owner) unless replace_existing
218
+ record
226
219
  end
227
220
 
228
- module ClassMethods
229
- module JoinDependency
230
- def self.included(base)
231
- base.alias_method_chain :construct_association, :inverse_of
232
- end
221
+ def we_can_set_the_inverse_on_this?(record)
222
+ inverse = @reflection.inverse_of
223
+ return !inverse.nil?
224
+ end
225
+ end
233
226
 
234
- def construct_association_with_inverse_of(record, join, row)
235
- association = construct_association_without_inverse_of(record, join, row) or
236
- return nil
237
- association_proxy = record.send(join.reflection.name)
238
- association_proxy.__send__(:set_inverse_instance, association, record)
239
- end
227
+ module ClassMethods
228
+ module JoinDependency
229
+ def self.included(base)
230
+ base.alias_method_chain :construct_association, :inverse_of
231
+ end
232
+
233
+ def construct_association_with_inverse_of(record, join, row)
234
+ association = construct_association_without_inverse_of(record, join, row) or
235
+ return nil
236
+ association_proxy = record.send(join.reflection.name)
237
+ association_proxy.__send__(:set_inverse_instance, association, record)
238
+ return association
240
239
  end
241
240
  end
242
241
  end
242
+ end
243
243
 
244
- module AssociationPreload
245
- def self.included(base)
246
- base.extend ClassMethods
247
- base.metaclass.alias_method_chain :add_preloaded_records_to_collection, :inverse_of
248
- base.metaclass.alias_method_chain :set_association_single_records, :inverse_of
249
- end
244
+ module AssociationPreload
245
+ def self.included(base)
246
+ base.extend ClassMethods
247
+ base.metaclass.alias_method_chain :add_preloaded_records_to_collection, :inverse_of
248
+ base.metaclass.alias_method_chain :set_association_single_records, :inverse_of
249
+ end
250
250
 
251
- module ClassMethods
252
- def add_preloaded_records_to_collection_with_inverse_of(parent_records, reflection_name, associated_record)
253
- value = add_preloaded_records_to_collection_without_inverse_of(parent_records, reflection_name, associated_record)
254
- parent_records.each do |parent_record|
255
- association_proxy = parent_record.send(reflection_name)
256
- association_proxy.__send__(:set_inverse_instance, associated_record, parent_record)
257
- end
258
- value
251
+ module ClassMethods
252
+ def add_preloaded_records_to_collection_with_inverse_of(parent_records, reflection_name, associated_record)
253
+ value = add_preloaded_records_to_collection_without_inverse_of(parent_records, reflection_name, associated_record)
254
+ parent_records.each do |parent_record|
255
+ association_proxy = parent_record.send(reflection_name)
256
+ association_proxy.__send__(:set_inverse_instance, associated_record, parent_record)
259
257
  end
258
+ value
259
+ end
260
260
 
261
- def set_association_single_records_with_inverse_of(id_to_record_map, reflection_name, associated_records, key)
262
- value = set_association_single_records_without_inverse_of(id_to_record_map, reflection_name, associated_records, key)
263
- associated_records.each do |associated_record|
264
- mapped_records = id_to_record_map[associated_record[key].to_s]
265
- mapped_records.each do |mapped_record|
266
- association_proxy = mapped_record.send(reflection_name)
267
- association_proxy.__send__(:set_inverse_instance, associated_record, mapped_record)
268
- end
261
+ def set_association_single_records_with_inverse_of(id_to_record_map, reflection_name, associated_records, key)
262
+ value = set_association_single_records_without_inverse_of(id_to_record_map, reflection_name, associated_records, key)
263
+ associated_records.each do |associated_record|
264
+ mapped_records = id_to_record_map[associated_record[key].to_s]
265
+ mapped_records.each do |mapped_record|
266
+ association_proxy = mapped_record.send(reflection_name)
267
+ association_proxy.__send__(:set_inverse_instance, associated_record, mapped_record)
269
268
  end
270
- value
271
269
  end
270
+ value
272
271
  end
273
272
  end
274
273
  end
274
+ end
275
275
 
276
- ActiveRecord::InverseOfAssociationNotFoundError = InverseOf::InverseOfAssociationNotFoundError
277
- ActiveRecord::Associations::AssociationCollection.send :include, InverseOf::Associations::AssociationCollection
278
- ActiveRecord::Associations::AssociationProxy.send :include, InverseOf::Associations::AssociationProxy
279
- ActiveRecord::Associations::BelongsToAssociation.send :include, InverseOf::Associations::BelongsToAssociation
280
- ActiveRecord::Associations::BelongsToPolymorphicAssociation.send :include, InverseOf::Associations::BelongsToPolymorphicAssociation
281
- ActiveRecord::Associations::HasManyAssociation.send :include, InverseOf::Associations::HasManyAssociation
282
- ActiveRecord::Associations::HasManyThroughAssociation.send :include, InverseOf::Associations::HasManyThroughAssociation
283
- ActiveRecord::Associations::HasOneAssociation.send :include, InverseOf::Associations::HasOneAssociation
284
- ActiveRecord::Associations::ClassMethods::JoinDependency.send :include, InverseOf::Associations::ClassMethods::JoinDependency
285
- ActiveRecord::Reflection.send :include, InverseOf::Reflection
286
- ActiveRecord::Base.send :include, InverseOf::AssociationPreload
287
-
288
- module ActiveRecord::Associations::ClassMethods
289
- @@valid_keys_for_has_many_association << :inverse_of
290
- @@valid_keys_for_has_one_association << :inverse_of
291
- @@valid_keys_for_belongs_to_association << :inverse_of
292
- end
276
+ ActiveRecord::InverseOfAssociationNotFoundError = InverseOf::InverseOfAssociationNotFoundError
277
+ ActiveRecord::Associations::AssociationCollection.send :include, InverseOf::Associations::AssociationCollection
278
+ ActiveRecord::Associations::AssociationProxy.send :include, InverseOf::Associations::AssociationProxy
279
+ ActiveRecord::Associations::BelongsToAssociation.send :include, InverseOf::Associations::BelongsToAssociation
280
+ ActiveRecord::Associations::BelongsToPolymorphicAssociation.send :include, InverseOf::Associations::BelongsToPolymorphicAssociation
281
+ ActiveRecord::Associations::HasManyAssociation.send :include, InverseOf::Associations::HasManyAssociation
282
+ ActiveRecord::Associations::HasManyThroughAssociation.send :include, InverseOf::Associations::HasManyThroughAssociation
283
+ ActiveRecord::Associations::HasOneAssociation.send :include, InverseOf::Associations::HasOneAssociation
284
+ ActiveRecord::Associations::ClassMethods::JoinDependency.send :include, InverseOf::Associations::ClassMethods::JoinDependency
285
+ ActiveRecord::Reflection.send :include, InverseOf::Reflection
286
+ ActiveRecord::Base.send :include, InverseOf::AssociationPreload
287
+
288
+ module ActiveRecord::Associations::ClassMethods
289
+ @@valid_keys_for_has_many_association << :inverse_of
290
+ @@valid_keys_for_has_one_association << :inverse_of
291
+ @@valid_keys_for_belongs_to_association << :inverse_of
293
292
  end