dm-core 0.9.2 → 0.9.3

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.
Files changed (84) hide show
  1. data/.autotest +26 -0
  2. data/{CHANGELOG → History.txt} +78 -77
  3. data/Manifest.txt +123 -0
  4. data/{README → README.txt} +0 -0
  5. data/Rakefile +29 -0
  6. data/SPECS +63 -0
  7. data/TODO +1 -0
  8. data/lib/dm-core.rb +6 -1
  9. data/lib/dm-core/adapters/data_objects_adapter.rb +29 -32
  10. data/lib/dm-core/adapters/mysql_adapter.rb +1 -1
  11. data/lib/dm-core/adapters/postgres_adapter.rb +1 -1
  12. data/lib/dm-core/adapters/sqlite3_adapter.rb +2 -2
  13. data/lib/dm-core/associations.rb +26 -0
  14. data/lib/dm-core/associations/many_to_many.rb +34 -25
  15. data/lib/dm-core/associations/many_to_one.rb +4 -4
  16. data/lib/dm-core/associations/one_to_many.rb +48 -13
  17. data/lib/dm-core/associations/one_to_one.rb +4 -4
  18. data/lib/dm-core/associations/relationship.rb +144 -42
  19. data/lib/dm-core/associations/relationship_chain.rb +31 -24
  20. data/lib/dm-core/auto_migrations.rb +0 -4
  21. data/lib/dm-core/collection.rb +40 -7
  22. data/lib/dm-core/dependency_queue.rb +31 -0
  23. data/lib/dm-core/hook.rb +2 -2
  24. data/lib/dm-core/is.rb +2 -2
  25. data/lib/dm-core/logger.rb +10 -10
  26. data/lib/dm-core/model.rb +94 -41
  27. data/lib/dm-core/property.rb +72 -41
  28. data/lib/dm-core/property_set.rb +8 -14
  29. data/lib/dm-core/query.rb +34 -9
  30. data/lib/dm-core/repository.rb +0 -0
  31. data/lib/dm-core/resource.rb +13 -13
  32. data/lib/dm-core/scope.rb +25 -2
  33. data/lib/dm-core/type.rb +3 -3
  34. data/lib/dm-core/types/discriminator.rb +10 -8
  35. data/lib/dm-core/types/object.rb +4 -0
  36. data/lib/dm-core/types/paranoid_boolean.rb +15 -4
  37. data/lib/dm-core/types/paranoid_datetime.rb +15 -4
  38. data/lib/dm-core/version.rb +3 -0
  39. data/script/all +5 -0
  40. data/script/performance.rb +191 -0
  41. data/script/profile.rb +86 -0
  42. data/spec/integration/association_spec.rb +288 -204
  43. data/spec/integration/association_through_spec.rb +9 -3
  44. data/spec/integration/associations/many_to_many_spec.rb +97 -31
  45. data/spec/integration/associations/many_to_one_spec.rb +41 -6
  46. data/spec/integration/associations/one_to_many_spec.rb +18 -2
  47. data/spec/integration/auto_migrations_spec.rb +0 -0
  48. data/spec/integration/collection_spec.rb +89 -42
  49. data/spec/integration/dependency_queue_spec.rb +58 -0
  50. data/spec/integration/model_spec.rb +67 -8
  51. data/spec/integration/postgres_adapter_spec.rb +19 -20
  52. data/spec/integration/property_spec.rb +17 -8
  53. data/spec/integration/query_spec.rb +273 -191
  54. data/spec/integration/resource_spec.rb +108 -10
  55. data/spec/integration/strategic_eager_loading_spec.rb +138 -0
  56. data/spec/integration/transaction_spec.rb +3 -3
  57. data/spec/integration/type_spec.rb +121 -0
  58. data/spec/lib/logging_helper.rb +18 -0
  59. data/spec/lib/model_loader.rb +91 -0
  60. data/spec/lib/publicize_methods.rb +28 -0
  61. data/spec/models/vehicles.rb +34 -0
  62. data/spec/models/zoo.rb +48 -0
  63. data/spec/spec.opts +3 -0
  64. data/spec/spec_helper.rb +25 -62
  65. data/spec/unit/adapters/data_objects_adapter_spec.rb +1 -0
  66. data/spec/unit/associations/many_to_many_spec.rb +3 -0
  67. data/spec/unit/associations/many_to_one_spec.rb +9 -1
  68. data/spec/unit/associations/one_to_many_spec.rb +12 -4
  69. data/spec/unit/associations/relationship_spec.rb +19 -15
  70. data/spec/unit/associations_spec.rb +37 -0
  71. data/spec/unit/collection_spec.rb +8 -0
  72. data/spec/unit/data_mapper_spec.rb +14 -0
  73. data/spec/unit/model_spec.rb +2 -2
  74. data/spec/unit/property_set_spec.rb +0 -13
  75. data/spec/unit/property_spec.rb +92 -21
  76. data/spec/unit/query_spec.rb +49 -4
  77. data/spec/unit/resource_spec.rb +122 -60
  78. data/spec/unit/scope_spec.rb +11 -0
  79. data/tasks/ci.rb +68 -0
  80. data/tasks/dm.rb +63 -0
  81. data/tasks/doc.rb +20 -0
  82. data/tasks/hoe.rb +38 -0
  83. data/tasks/install.rb +20 -0
  84. metadata +63 -22
@@ -10,6 +10,7 @@ module DataMapper
10
10
  undef_method :get_parent
11
11
  undef_method :attach_parent
12
12
 
13
+ # @api private
13
14
  def child_model
14
15
  near_relationship.child_model
15
16
  end
@@ -18,38 +19,19 @@ module DataMapper
18
19
  def get_children(parent, options = {}, finder = :all, *args)
19
20
  query = @query.merge(options).merge(child_key.to_query(parent_key.get(parent)))
20
21
 
21
- query[:links] = links
22
+ query[:links] = links
23
+ query[:unique] = true
22
24
 
23
- DataMapper.repository(parent.repository.name) do
25
+ with_repository(parent) do
24
26
  results = grandchild_model.send(finder, *(args << query))
25
27
  # FIXME: remove the need for the uniq.freeze
26
- finder == :all ? (@mutable ? results.uniq : results.uniq.freeze) : results
28
+ finder == :all ? (@mutable ? results : results.freeze) : results
27
29
  end
28
30
  end
29
31
 
30
32
  private
31
33
 
32
- def near_relationship
33
- parent_model.relationships[@near_relationship_name]
34
- end
35
-
36
- def links
37
- if remote_relationship.kind_of?(RelationshipChain)
38
- remote_relationship.instance_eval { links } + [remote_relationship.instance_eval { near_relationship } ]
39
- else
40
- [ remote_relationship ]
41
- end
42
- end
43
-
44
- def remote_relationship
45
- near_relationship.child_model.relationships[@remote_relationship_name] ||
46
- near_relationship.child_model.relationships[@remote_relationship_name.to_s.singularize.to_sym]
47
- end
48
-
49
- def grandchild_model
50
- Class === @child_model ? @child_model : self.class.find_const(@child_model)
51
- end
52
-
34
+ # @api private
53
35
  def initialize(options)
54
36
  if (missing_options = OPTIONS - [ :min, :max ] - options.keys ).any?
55
37
  raise ArgumentError, "The options #{missing_options * ', '} are required", caller
@@ -69,6 +51,31 @@ module DataMapper
69
51
  @extra_links = []
70
52
  @options = options
71
53
  end
54
+
55
+ # @api private
56
+ def near_relationship
57
+ parent_model.relationships[@near_relationship_name]
58
+ end
59
+
60
+ # @api private
61
+ def links
62
+ if remote_relationship.kind_of?(RelationshipChain)
63
+ remote_relationship.instance_eval { links } + [remote_relationship.instance_eval { near_relationship } ]
64
+ else
65
+ [ remote_relationship ]
66
+ end
67
+ end
68
+
69
+ # @api private
70
+ def remote_relationship
71
+ near_relationship.child_model.relationships[@remote_relationship_name] ||
72
+ near_relationship.child_model.relationships[@remote_relationship_name.to_s.singularize.to_sym]
73
+ end
74
+
75
+ # @api private
76
+ def grandchild_model
77
+ Class === @child_model ? @child_model : (Class === @parent_model ? @parent_model.find_const(@child_model) : Object.find_const(@child_model))
78
+ end
72
79
  end # class Relationship
73
80
  end # module Associations
74
81
  end # module DataMapper
@@ -37,9 +37,7 @@ module DataMapper
37
37
  if self.superclass != Object
38
38
  self.superclass.auto_migrate!(repository_name)
39
39
  else
40
- repository_name ||= default_repository_name
41
40
  repository(repository_name) do |r|
42
- (relationships(r.name)||{}).each_value { |relationship| relationship.child_key }
43
41
  r.adapter.destroy_model_storage(r, self)
44
42
  r.adapter.create_model_storage(r, self)
45
43
  end
@@ -52,9 +50,7 @@ module DataMapper
52
50
  #
53
51
  # @param Symbol repository_name the repository to be migrated
54
52
  def auto_upgrade!(repository_name = nil)
55
- repository_name ||= default_repository_name
56
53
  repository(repository_name) do |r|
57
- (relationships(r.name)||{}).each_value { |relationship| relationship.child_key }
58
54
  r.adapter.upgrade_model_storage(r, self)
59
55
  end
60
56
  end
@@ -50,6 +50,7 @@ module DataMapper
50
50
  #
51
51
  # @api public
52
52
  def get(*key)
53
+ key = model.typecast_key(key)
53
54
  if loaded?
54
55
  # loop over the collection to find the matching resource
55
56
  detect { |resource| resource.key == key }
@@ -318,8 +319,22 @@ module DataMapper
318
319
  self
319
320
  end
320
321
 
322
+ # builds a new resource and appends it to the collection
323
+ #
324
+ # @param Hash[Symbol => Object] attributes attributes which
325
+ # the new resource should have.
326
+ #
327
+ # @api public
328
+ def build(attributes = {})
329
+ repository.scope do
330
+ resource = model.new(default_attributes.merge(attributes))
331
+ self << resource
332
+ resource
333
+ end
334
+ end
335
+
321
336
  ##
322
- # creates a new array, saves it, and << it onto the collection
337
+ # creates a new resource, saves it, and appends it to the collection
323
338
  #
324
339
  # @param Hash[Symbol => Object] attributes attributes which
325
340
  # the new resource should have.
@@ -462,12 +477,26 @@ module DataMapper
462
477
  default_attributes
463
478
  end
464
479
 
480
+ ##
481
+ # check to see if collection can respond to the method
482
+ #
483
+ # @param method [Symbol] method to check in the object
484
+ # @param include_private [FalseClass, TrueClass] if set to true,
485
+ # collection will check private methods
486
+ #
487
+ # @return [TrueClass, FalseClass]
488
+ # TrueClass indicates the method can be responded to by the collection
489
+ # FalseClass indicates the method can not be responded to by the collection
490
+ #
491
+ # @api public
492
+ def respond_to?(method, include_private = false)
493
+ super || model.public_methods(false).include?(method.to_s) || relationships.has_key?(method)
494
+ end
495
+
465
496
  protected
466
497
 
467
498
  ##
468
499
  # @api private
469
- #
470
- # @api public
471
500
  def model
472
501
  query.model
473
502
  end
@@ -579,7 +608,11 @@ module DataMapper
579
608
  ##
580
609
  # @api private
581
610
  def method_missing(method, *args, &block)
582
- if relationship = relationships[method]
611
+ if model.public_methods(false).include?(method.to_s)
612
+ model.send(:with_scope, query) do
613
+ model.send(method, *args, &block)
614
+ end
615
+ elsif relationship = relationships[method]
583
616
  klass = model == relationship.child_model ? relationship.parent_model : relationship.child_model
584
617
 
585
618
  # TODO: when self.query includes an offset/limit use it as a
@@ -595,10 +628,10 @@ module DataMapper
595
628
  :links => self.query.links + [ relationship ]
596
629
  )
597
630
 
598
- return klass.all(query, &block)
631
+ klass.all(query, &block)
632
+ else
633
+ super
599
634
  end
600
-
601
- super
602
635
  end
603
636
  end # class Collection
604
637
  end # module DataMapper
@@ -0,0 +1,31 @@
1
+ module DataMapper
2
+ ##
3
+ #
4
+ # DataMapper's DependencyQueue is used to store callbacks for classes which
5
+ # may or may not be loaded already.
6
+ #
7
+ class DependencyQueue
8
+ def initialize
9
+ @dependencies = Hash.new { |h,k| h[k] = [] }
10
+ end
11
+
12
+ def add(class_name, &callback)
13
+ @dependencies[class_name] << callback
14
+ resolve!
15
+ end
16
+
17
+ def resolve!
18
+ @dependencies.each do |class_name, callbacks|
19
+ begin
20
+ klass = Object.find_const(class_name)
21
+ callbacks.each do |callback|
22
+ callback.call(klass)
23
+ end
24
+ callbacks.clear
25
+ rescue NameError
26
+ end
27
+ end
28
+ end
29
+
30
+ end # class DependencyQueue
31
+ end # module DataMapper
data/lib/dm-core/hook.rb CHANGED
@@ -1,10 +1,10 @@
1
1
  module DataMapper
2
2
  module Hook
3
3
  def self.included(model)
4
- model.class_eval %{
4
+ model.class_eval <<-EOS, __FILE__, __LINE__
5
5
  include Extlib::Hook
6
6
  register_instance_hooks :save, :create, :update, :destroy
7
- }
7
+ EOS
8
8
  end
9
9
  end
10
10
  DataMapper::Resource.append_inclusions Hook
data/lib/dm-core/is.rb CHANGED
@@ -1,11 +1,11 @@
1
1
  module DataMapper
2
2
  module Is
3
3
 
4
- def is(plugin,*pars)
4
+ def is(plugin, *pars, &block)
5
5
  generator_method = "is_#{plugin}".to_sym
6
6
 
7
7
  if self.respond_to?(generator_method)
8
- self.send(generator_method,*pars)
8
+ self.send(generator_method, *pars, &block)
9
9
  else
10
10
  raise PluginNotFoundError, "could not find plugin named #{plugin}"
11
11
  end
@@ -213,19 +213,19 @@ module DataMapper
213
213
  # :off only gets a off? method
214
214
  LEVELS.each_pair do |name, number|
215
215
  unless name.to_s == 'off'
216
- class_eval <<-EOS
217
- # DOC
218
- def #{name}(message)
219
- self.<<( prep_msg(message, "#{name}") ) if #{name}?
220
- end
216
+ class_eval <<-EOS, __FILE__, __LINE__
217
+ # DOC
218
+ def #{name}(message)
219
+ self.<<( prep_msg(message, "#{name}") ) if #{name}?
220
+ end
221
221
  EOS
222
222
  end
223
223
 
224
- class_eval <<-EOS
225
- # DOC
226
- def #{name}?
227
- #{number} >= level
228
- end
224
+ class_eval <<-EOS, __FILE__, __LINE__
225
+ # DOC
226
+ def #{name}?
227
+ #{number} >= level
228
+ end
229
229
  EOS
230
230
  end
231
231
 
data/lib/dm-core/model.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require 'set'
2
+
1
3
  module DataMapper
2
4
  module Model
3
5
  ##
@@ -21,23 +23,43 @@ module DataMapper
21
23
  extra_extensions.concat extensions
22
24
  true
23
25
  end
24
-
26
+
25
27
  def self.extra_extensions
26
28
  @extra_extensions ||= []
27
29
  end
28
-
30
+
29
31
  def self.extended(model)
30
- model.instance_variable_set(:@storage_names, Hash.new { |h,k| h[k] = repository(k).adapter.resource_naming_convention.call(model.instance_eval { default_storage_name }) })
32
+ model.instance_variable_set(:@storage_names, Hash.new { |h,k| h[k] = repository(k).adapter.resource_naming_convention.call(model.send(:default_storage_name)) })
31
33
  model.instance_variable_set(:@properties, Hash.new { |h,k| h[k] = k == Repository.default_name ? PropertySet.new : h[Repository.default_name].dup })
32
34
  extra_extensions.each { |extension| model.extend(extension) }
33
35
  end
34
36
 
35
37
  def inherited(target)
36
- target.instance_variable_set(:@storage_names, @storage_names.dup)
37
- target.instance_variable_set(:@properties, Hash.new { |h,k| h[k] = k == Repository.default_name ? self.properties(Repository.default_name).dup(target) : h[Repository.default_name].dup })
38
+ target.instance_variable_set(:@storage_names, @storage_names.dup)
39
+ target.instance_variable_set(:@properties, Hash.new { |h,k| h[k] = k == Repository.default_name ? PropertySet.new : h[Repository.default_name].dup })
40
+ target.instance_variable_set(:@base_model, self.base_model)
41
+ target.instance_variable_set(:@paranoid_properties, @paranoid_properties)
42
+ target.instance_variable_set(:@validations, @validations.dup) if self.respond_to?(:validators)
43
+
44
+ @properties.each do |repository_name,properties|
45
+ repository(repository_name) do
46
+ properties.each do |property|
47
+ next if target.properties(repository_name).has_property?(property.name)
48
+ target.property(property.name, property.type, property.options.dup)
49
+ end
50
+ end
51
+ end
38
52
 
39
53
  if @relationships
40
- duped_relationships = {}; @relationships.each_pair{ |repos, rels| duped_relationships[repos] = rels.dup}
54
+ duped_relationships = Hash.new { |h,k| h[k] = {} }
55
+ @relationships.each do |repository_name,relationships|
56
+ relationships.each do |name, relationship|
57
+ dup = relationship.dup
58
+ dup.instance_variable_set(:@child_model, target) if dup.instance_variable_get(:@child_model) == self
59
+ dup.instance_variable_set(:@parent_model, target) if dup.instance_variable_get(:@parent_model) == self
60
+ duped_relationships[repository_name][name] = dup
61
+ end
62
+ end
41
63
  target.instance_variable_set(:@relationships, duped_relationships)
42
64
  end
43
65
  end
@@ -54,6 +76,14 @@ module DataMapper
54
76
  model
55
77
  end
56
78
 
79
+ def base_model
80
+ @base_model ||= self
81
+ end
82
+
83
+ def repository_name
84
+ Repository.context.any? ? Repository.context.last.name : default_repository_name
85
+ end
86
+
57
87
  ##
58
88
  # Get the repository with a given name, or the default one for the current
59
89
  # context, or the default one for this class.
@@ -71,7 +101,7 @@ module DataMapper
71
101
  # united in the concept of explicitness over implicitness. That is - the explicit wish of the
72
102
  # caller (+name+) should be given more priority than the implicit wish of the caller (Repository.context.last).
73
103
  #
74
- DataMapper.repository(*Array(name || (Repository.context.last ? nil : default_repository_name)), &block)
104
+ DataMapper.repository(name || repository_name, &block)
75
105
  end
76
106
 
77
107
  ##
@@ -103,11 +133,11 @@ module DataMapper
103
133
  create_property_getter(property)
104
134
  create_property_setter(property)
105
135
 
106
- @properties[repository.name] << property
136
+ @properties[repository_name] << property
107
137
 
108
138
  # Add property to the other mappings as well if this is for the default
109
139
  # repository.
110
- if repository.name == default_repository_name
140
+ if repository_name == default_repository_name
111
141
  @properties.each_pair do |repository_name, properties|
112
142
  next if repository_name == default_repository_name
113
143
  properties << property
@@ -123,35 +153,42 @@ module DataMapper
123
153
  context = :default if context == true
124
154
 
125
155
  Array(context).each do |item|
126
- @properties[repository.name].lazy_context(item) << name
156
+ @properties[repository_name].lazy_context(item) << name
157
+ end
158
+ end
159
+
160
+ # add the property to the child classes only if the property was
161
+ # added after the child classes' properties have been copied from
162
+ # the parent
163
+ if respond_to?(:descendants)
164
+ descendants.each do |model|
165
+ next if model.properties(repository_name).has_property?(name)
166
+ model.property(name, type, options)
127
167
  end
128
168
  end
129
169
 
130
170
  property
131
171
  end
132
172
 
133
- # TODO: make this a Set?
134
173
  def repositories
135
- [ repository ] + @properties.keys.collect { |repository_name| DataMapper.repository(repository_name) }
174
+ [ repository ].to_set + @properties.keys.collect { |repository_name| DataMapper.repository(repository_name) }
136
175
  end
137
176
 
138
177
  def properties(repository_name = default_repository_name)
139
178
  @properties[repository_name]
140
179
  end
141
180
 
181
+ # @api private
142
182
  def properties_with_subclasses(repository_name = default_repository_name)
143
- #return properties if we're not interested in sti
144
- if @properties[repository_name].inheritance_property.nil?
145
- @properties[repository_name]
146
- else
147
- props = @properties[repository_name].dup
148
- self.child_classes.each do |subclass|
149
- subclass.properties(repository_name).each do |subprop|
150
- props << subprop if not props.any? { |prop| prop.name == subprop.name }
151
- end
183
+ properties = PropertySet.new
184
+ ([ self ].to_set + (respond_to?(:descendants) ? descendants : [])).each do |model|
185
+ model.relationships(repository_name).each_value { |relationship| relationship.child_key }
186
+ model.many_to_one_relationships.each do |relationship| relationship.child_key end
187
+ model.properties(repository_name).each do |property|
188
+ properties << property unless properties.has_property?(property.name)
152
189
  end
153
- props
154
190
  end
191
+ properties
155
192
  end
156
193
 
157
194
  def key(repository_name = default_repository_name)
@@ -167,6 +204,7 @@ module DataMapper
167
204
  end
168
205
 
169
206
  def get(*key)
207
+ key = typecast_key(key)
170
208
  repository.identity_map(self).get(key) || first(to_query(repository, key))
171
209
  end
172
210
 
@@ -200,7 +238,7 @@ module DataMapper
200
238
  resource = allocate
201
239
  query = query.dup
202
240
 
203
- properties(repository.name).key.each do |property|
241
+ properties(repository_name).key.each do |property|
204
242
  if value = query.delete(property.name)
205
243
  resource.send("#{property.name}=", value)
206
244
  end
@@ -223,12 +261,10 @@ module DataMapper
223
261
  end
224
262
 
225
263
  ##
226
- # Dangerous version of #create. Raises if there is a failure
227
- #
228
- # @see DataMapper::Resource#create
229
- # @param <Hash(Symbol => Object)> attributes hash of attributes to set
230
- # @raise <PersistenceError> The resource could not be saved
264
+ # This method is deprecated, and will be removed from dm-core.
265
+ #
231
266
  def create!(attributes = {})
267
+ warn("Model#create! is deprecated. It is moving to dm-validations, and will be used to create a record without validations")
232
268
  resource = create(attributes)
233
269
  raise PersistenceError, "Resource not saved: :new_record => #{resource.new_record?}, :dirty_attributes => #{resource.dirty_attributes.inspect}" if resource.new_record?
234
270
  resource
@@ -280,7 +316,7 @@ module DataMapper
280
316
  when :hash
281
317
  resource.original_values[property.name] = value.dup.hash unless resource.original_values.has_key?(property.name) rescue value.hash
282
318
  when :load
283
- resource.original_values[property.name] = value unless resource.original_values.has_key?(property.name)
319
+ resource.original_values[property.name] = value unless resource.original_values.has_key?(property.name)
284
320
  end
285
321
  end
286
322
  end
@@ -290,20 +326,29 @@ module DataMapper
290
326
 
291
327
  # TODO: spec this
292
328
  def to_query(repository, key, query = {})
293
- conditions = Hash[ *self.key(repository.name).zip(key).flatten ]
329
+ conditions = Hash[ *self.key(repository_name).zip(key).flatten ]
294
330
  Query.new(repository, self, query.merge(conditions))
295
331
  end
296
332
 
297
- private
298
-
299
- def default_storage_name
300
- self.name
333
+ def typecast_key(key)
334
+ self.key(repository_name).zip(key).map { |k, v| k.typecast(v) }
301
335
  end
302
336
 
303
337
  def default_repository_name
304
338
  Repository.default_name
305
339
  end
306
340
 
341
+ def paranoid_properties
342
+ @paranoid_properties ||= {}
343
+ @paranoid_properties
344
+ end
345
+
346
+ private
347
+
348
+ def default_storage_name
349
+ self.name
350
+ end
351
+
307
352
  def scoped_query(query = self.query)
308
353
  assert_kind_of 'query', query, Query, Hash
309
354
 
@@ -315,7 +360,15 @@ module DataMapper
315
360
  query
316
361
  end
317
362
 
318
- self.query ? self.query.merge(query) : query
363
+ if self.query
364
+ self.query.merge(query)
365
+ else
366
+ merge_with_default_scope(query)
367
+ end
368
+ end
369
+
370
+ def set_paranoid_property(name, &block)
371
+ self.paranoid_properties[name] = block
319
372
  end
320
373
 
321
374
  # defines the getter for the property
@@ -327,7 +380,7 @@ module DataMapper
327
380
  end
328
381
  EOS
329
382
 
330
- if property.primitive == TrueClass && !property.model.instance_methods.include?(property.name.to_s)
383
+ if property.primitive == TrueClass && !instance_methods.include?(property.name.to_s)
331
384
  class_eval <<-EOS, __FILE__, __LINE__
332
385
  #{property.reader_visibility}
333
386
  alias #{property.name} #{property.getter}
@@ -337,7 +390,7 @@ module DataMapper
337
390
 
338
391
  # defines the setter for the property
339
392
  def create_property_setter(property)
340
- unless instance_methods.include?(property.name.to_s + '=')
393
+ unless instance_methods.include?("#{property.name}=")
341
394
  class_eval <<-EOS, __FILE__, __LINE__
342
395
  #{property.writer_visibility}
343
396
  def #{property.name}=(value)
@@ -353,14 +406,14 @@ module DataMapper
353
406
  # a missing module can cause misleading recursive errors.
354
407
  raise NotImplementedError.new
355
408
  end
356
-
357
- def method_missing(method, *args, &block)
358
- if relationship = self.relationships(repository.name)[method]
409
+
410
+ def method_missing(method, *args, &block)
411
+ if relationship = self.relationships(repository_name)[method]
359
412
  klass = self == relationship.child_model ? relationship.parent_model : relationship.child_model
360
413
  return DataMapper::Query::Path.new(repository, [ relationship ], klass)
361
414
  end
362
415
 
363
- if property = properties(repository.name)[method]
416
+ if property = properties(repository_name)[method]
364
417
  return property
365
418
  end
366
419