dm-core 1.1.0 → 1.2.0.rc1
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.
- data/Gemfile +13 -11
- data/README.rdoc +1 -1
- data/Rakefile +1 -2
- data/VERSION +1 -1
- data/dm-core.gemspec +30 -176
- data/lib/dm-core.rb +32 -67
- data/lib/dm-core/adapters/abstract_adapter.rb +1 -2
- data/lib/dm-core/associations/many_to_many.rb +11 -5
- data/lib/dm-core/associations/many_to_one.rb +17 -2
- data/lib/dm-core/associations/one_to_many.rb +16 -0
- data/lib/dm-core/backwards.rb +13 -0
- data/lib/dm-core/collection.rb +1 -1
- data/lib/dm-core/model.rb +99 -41
- data/lib/dm-core/model/property.rb +24 -27
- data/lib/dm-core/model/relationship.rb +22 -28
- data/lib/dm-core/property.rb +37 -50
- data/lib/dm-core/property/boolean.rb +6 -10
- data/lib/dm-core/property/date.rb +0 -2
- data/lib/dm-core/property/date_time.rb +0 -2
- data/lib/dm-core/property/decimal.rb +5 -1
- data/lib/dm-core/property/discriminator.rb +24 -26
- data/lib/dm-core/property/float.rb +5 -1
- data/lib/dm-core/property/numeric.rb +6 -9
- data/lib/dm-core/property/string.rb +2 -1
- data/lib/dm-core/property/time.rb +0 -2
- data/lib/dm-core/property/typecast/time.rb +7 -2
- data/lib/dm-core/property_set.rb +1 -3
- data/lib/dm-core/query.rb +3 -10
- data/lib/dm-core/query/conditions/comparison.rb +5 -1
- data/lib/dm-core/query/conditions/operation.rb +1 -1
- data/lib/dm-core/relationship_set.rb +0 -2
- data/lib/dm-core/resource.rb +27 -28
- data/lib/dm-core/resource/{state.rb → persistence_state.rb} +2 -2
- data/lib/dm-core/resource/{state → persistence_state}/clean.rb +4 -4
- data/lib/dm-core/resource/{state → persistence_state}/deleted.rb +2 -2
- data/lib/dm-core/resource/{state → persistence_state}/dirty.rb +2 -2
- data/lib/dm-core/resource/{state → persistence_state}/immutable.rb +3 -3
- data/lib/dm-core/resource/{state → persistence_state}/persisted.rb +3 -3
- data/lib/dm-core/resource/{state → persistence_state}/transient.rb +3 -3
- data/lib/dm-core/spec/lib/adapter_helpers.rb +2 -5
- data/lib/dm-core/spec/setup.rb +3 -2
- data/lib/dm-core/spec/shared/public/property_spec.rb +8 -0
- data/lib/dm-core/spec/shared/resource_spec.rb +14 -0
- data/lib/dm-core/spec/shared/semipublic/property_spec.rb +1 -1
- data/lib/dm-core/support/descendant_set.rb +0 -2
- data/lib/dm-core/support/ext/array.rb +0 -19
- data/lib/dm-core/support/ext/blank.rb +1 -0
- data/lib/dm-core/support/hook.rb +0 -3
- data/lib/dm-core/support/naming_conventions.rb +6 -0
- data/lib/dm-core/support/ordered_set.rb +0 -2
- data/lib/dm-core/support/subject_set.rb +0 -2
- data/lib/dm-core/version.rb +1 -1
- data/spec/public/associations/many_to_many_spec.rb +0 -1
- data/spec/public/model/property_spec.rb +55 -9
- data/spec/public/model/relationship_spec.rb +24 -2
- data/spec/public/model_spec.rb +32 -0
- data/spec/public/property/binary_spec.rb +14 -6
- data/spec/public/property/boolean_spec.rb +14 -6
- data/spec/public/property/class_spec.rb +14 -6
- data/spec/public/property/date_spec.rb +14 -6
- data/spec/public/property/date_time_spec.rb +14 -6
- data/spec/public/property/decimal_spec.rb +10 -2
- data/spec/public/property/discriminator_spec.rb +15 -1
- data/spec/public/property/float_spec.rb +14 -6
- data/spec/public/property/integer_spec.rb +14 -6
- data/spec/public/property/object_spec.rb +8 -0
- data/spec/public/property/serial_spec.rb +14 -6
- data/spec/public/property/string_spec.rb +14 -6
- data/spec/public/property/text_spec.rb +14 -6
- data/spec/public/property/time_spec.rb +14 -6
- data/spec/public/resource_spec.rb +58 -0
- data/spec/public/shared/finder_shared_spec.rb +8 -4
- data/spec/semipublic/associations/many_to_many_spec.rb +2 -0
- data/spec/semipublic/associations/many_to_one_spec.rb +2 -0
- data/spec/semipublic/associations/one_to_many_spec.rb +2 -0
- data/spec/semipublic/associations/one_to_one_spec.rb +2 -0
- data/spec/semipublic/property/binary_spec.rb +5 -5
- data/spec/semipublic/property/boolean_spec.rb +5 -5
- data/spec/semipublic/property/class_spec.rb +5 -5
- data/spec/semipublic/property/date_spec.rb +5 -5
- data/spec/semipublic/property/date_time_spec.rb +5 -5
- data/spec/semipublic/property/decimal_spec.rb +2 -2
- data/spec/semipublic/property/discriminator_spec.rb +5 -5
- data/spec/semipublic/property/float_spec.rb +5 -5
- data/spec/semipublic/property/integer_spec.rb +5 -5
- data/spec/semipublic/property/lookup_spec.rb +3 -3
- data/spec/semipublic/property/serial_spec.rb +5 -5
- data/spec/semipublic/property/string_spec.rb +5 -5
- data/spec/semipublic/property/text_spec.rb +5 -5
- data/spec/semipublic/property/time_spec.rb +5 -5
- data/spec/semipublic/query/conditions/comparison_spec.rb +44 -4
- data/spec/semipublic/query_spec.rb +2 -11
- data/spec/semipublic/resource/state/clean_spec.rb +6 -6
- data/spec/semipublic/resource/state/deleted_spec.rb +4 -4
- data/spec/semipublic/resource/state/dirty_spec.rb +8 -8
- data/spec/semipublic/resource/state/immutable_spec.rb +6 -6
- data/spec/semipublic/resource/state/transient_spec.rb +5 -5
- data/spec/semipublic/resource/state_spec.rb +15 -15
- data/spec/semipublic/shared/resource_shared_spec.rb +7 -1
- data/spec/semipublic/shared/resource_state_shared_spec.rb +8 -8
- data/spec/unit/array_spec.rb +0 -14
- data/spec/unit/blank_spec.rb +11 -0
- metadata +70 -188
- data/lib/dm-core/support/inflector.rb +0 -3
@@ -208,8 +208,7 @@ module DataMapper
|
|
208
208
|
#
|
209
209
|
# @api semipublic
|
210
210
|
def attributes_as_fields(attributes)
|
211
|
-
|
212
|
-
DataMapper::Ext::Array.to_hash(pairs)
|
211
|
+
Hash[ attributes.map { |property, value| [ property.field, property.dump(value) ] } ]
|
213
212
|
end
|
214
213
|
|
215
214
|
private
|
@@ -124,6 +124,14 @@ module DataMapper
|
|
124
124
|
@links.freeze
|
125
125
|
end
|
126
126
|
|
127
|
+
# Initialize the chain for "many to many" relationships
|
128
|
+
#
|
129
|
+
# @api public
|
130
|
+
def finalize
|
131
|
+
through
|
132
|
+
via
|
133
|
+
end
|
134
|
+
|
127
135
|
# @api private
|
128
136
|
def source_scope(source)
|
129
137
|
{ through.inverse => source }
|
@@ -248,15 +256,13 @@ module DataMapper
|
|
248
256
|
target_key.valid?(source_key.get(source))
|
249
257
|
end
|
250
258
|
|
251
|
-
# @api semipublic
|
252
259
|
chainable do
|
260
|
+
# @api semipublic
|
253
261
|
def many_to_one_options
|
254
262
|
{ :parent_key => target_key.map { |property| property.name } }
|
255
263
|
end
|
256
|
-
end
|
257
264
|
|
258
|
-
|
259
|
-
chainable do
|
265
|
+
# @api semipublic
|
260
266
|
def one_to_many_options
|
261
267
|
{ :parent_key => source_key.map { |property| property.name } }
|
262
268
|
end
|
@@ -359,7 +365,7 @@ module DataMapper
|
|
359
365
|
end
|
360
366
|
|
361
367
|
each do |resource|
|
362
|
-
resource.
|
368
|
+
resource.persistence_state = Resource::PersistenceState::Immutable.new(resource)
|
363
369
|
end
|
364
370
|
|
365
371
|
clear
|
@@ -4,7 +4,7 @@ module DataMapper
|
|
4
4
|
# Relationship class with implementation specific
|
5
5
|
# to n side of 1 to n association
|
6
6
|
class Relationship < Associations::Relationship
|
7
|
-
OPTIONS = superclass::OPTIONS.dup << :required << :key
|
7
|
+
OPTIONS = superclass::OPTIONS.dup << :required << :key << :unique
|
8
8
|
|
9
9
|
# @api semipublic
|
10
10
|
alias_method :source_repository_name, :child_repository_name
|
@@ -31,6 +31,11 @@ module DataMapper
|
|
31
31
|
@key
|
32
32
|
end
|
33
33
|
|
34
|
+
# @api semipublic
|
35
|
+
def unique?
|
36
|
+
!!@unique
|
37
|
+
end
|
38
|
+
|
34
39
|
# @deprecated
|
35
40
|
def nullable?
|
36
41
|
raise "#{self.class}#nullable? is deprecated, use #{self.class}#required? instead (#{caller.first})"
|
@@ -64,6 +69,14 @@ module DataMapper
|
|
64
69
|
# @api semipublic
|
65
70
|
alias_method :source_key, :child_key
|
66
71
|
|
72
|
+
# Initialize the foreign key property this "many to one"
|
73
|
+
# relationship uses to persist itself
|
74
|
+
#
|
75
|
+
# @api public
|
76
|
+
def finalize
|
77
|
+
child_key
|
78
|
+
end
|
79
|
+
|
67
80
|
# Returns a hash of conditions that scopes query that fetches
|
68
81
|
# target object
|
69
82
|
#
|
@@ -193,6 +206,7 @@ module DataMapper
|
|
193
206
|
|
194
207
|
@required = options.fetch(:required, true)
|
195
208
|
@key = options.fetch(:key, false)
|
209
|
+
@unique = options.fetch(:unique, false)
|
196
210
|
target_model ||= DataMapper::Inflector.camelize(name)
|
197
211
|
options = { :min => @required ? 1 : 0, :max => 1 }.update(options)
|
198
212
|
super
|
@@ -248,7 +262,8 @@ module DataMapper
|
|
248
262
|
options = DataMapper::Ext::Hash.only(target_property.options, :length, :precision, :scale).update(
|
249
263
|
:index => name,
|
250
264
|
:required => required?,
|
251
|
-
:key => key
|
265
|
+
:key => key?,
|
266
|
+
:unique => @unique
|
252
267
|
)
|
253
268
|
|
254
269
|
if target_property.primitive == Integer
|
@@ -100,6 +100,22 @@ module DataMapper
|
|
100
100
|
end
|
101
101
|
end
|
102
102
|
|
103
|
+
# initialize the inverse "many to one" relationships explicitly before
|
104
|
+
# initializing other relationships. This makes sure that foreign key
|
105
|
+
# properties always appear in the order they were declared.
|
106
|
+
#
|
107
|
+
# @api public
|
108
|
+
def finalize
|
109
|
+
child_model.relationships.each do |relationship|
|
110
|
+
# TODO: should this check #inverse?
|
111
|
+
# relationship.child_key if inverse?(relationship)
|
112
|
+
if relationship.kind_of?(Associations::ManyToOne::Relationship)
|
113
|
+
relationship.finalize
|
114
|
+
end
|
115
|
+
end
|
116
|
+
inverse.finalize
|
117
|
+
end
|
118
|
+
|
103
119
|
# @api semipublic
|
104
120
|
def default_for(source)
|
105
121
|
collection_for(source).replace(Array(super))
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "dm-core/support/deprecate"
|
2
|
+
|
3
|
+
module DataMapper
|
4
|
+
module Resource
|
5
|
+
extend Deprecate
|
6
|
+
|
7
|
+
deprecate :persisted_state, :persistence_state
|
8
|
+
deprecate :persisted_state=, :persistence_state=
|
9
|
+
deprecate :persisted_state?, :persistence_state?
|
10
|
+
|
11
|
+
end # module Resource
|
12
|
+
|
13
|
+
end # module DataMapper
|
data/lib/dm-core/collection.rb
CHANGED
data/lib/dm-core/model.rb
CHANGED
@@ -1,14 +1,10 @@
|
|
1
|
-
# TODO: add Model#create!, Model#update, Model#update!, Model#destroy and Model#destroy!
|
2
|
-
|
3
|
-
# TODO: DRY up raise_on_save_failure with attr_accessor_with_default
|
4
|
-
# once AS branch is merged in
|
5
|
-
|
6
1
|
module DataMapper
|
7
2
|
module Model
|
8
|
-
extend Chainable
|
9
|
-
|
10
3
|
include Enumerable
|
11
4
|
|
5
|
+
WRITER_METHOD_REGEXP = /=\z/.freeze
|
6
|
+
INVALID_WRITER_METHODS = %w[ == != === []= taguri= attributes= collection= persistence_state= raise_on_save_failure= ].to_set.freeze
|
7
|
+
|
12
8
|
# Creates a new Model class with its constant already set
|
13
9
|
#
|
14
10
|
# If a block is passed, it will be eval'd in the context of the new Model
|
@@ -132,6 +128,19 @@ module DataMapper
|
|
132
128
|
@raise_on_save_failure = raise_on_save_failure
|
133
129
|
end
|
134
130
|
|
131
|
+
# Finish model setup and verify it is valid
|
132
|
+
#
|
133
|
+
# @return [undefined]
|
134
|
+
#
|
135
|
+
# @api public
|
136
|
+
def finalize
|
137
|
+
finalize_relationships
|
138
|
+
finalize_allowed_writer_methods
|
139
|
+
assert_valid_name
|
140
|
+
assert_valid_properties
|
141
|
+
assert_valid_key
|
142
|
+
end
|
143
|
+
|
135
144
|
# Appends a module for inclusion into the model class after Resource.
|
136
145
|
#
|
137
146
|
# This is a useful way to extend Resource while still retaining a
|
@@ -211,15 +220,13 @@ module DataMapper
|
|
211
220
|
end
|
212
221
|
|
213
222
|
# @api private
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
descendant.instance_variable_set(:@default_order, @default_order.dup)
|
222
|
-
end
|
223
|
+
def inherited(descendant)
|
224
|
+
descendants << descendant
|
225
|
+
|
226
|
+
descendant.instance_variable_set(:@valid, false)
|
227
|
+
descendant.instance_variable_set(:@base_model, base_model)
|
228
|
+
descendant.instance_variable_set(:@storage_names, @storage_names.dup)
|
229
|
+
descendant.instance_variable_set(:@default_order, @default_order.dup)
|
223
230
|
end
|
224
231
|
|
225
232
|
# Gets the name of the storage receptacle for this resource in the given
|
@@ -564,8 +571,7 @@ module DataMapper
|
|
564
571
|
discriminator = properties(repository_name).discriminator
|
565
572
|
no_reload = !query.reload?
|
566
573
|
|
567
|
-
field_map = fields.map { |property| [ property, property.field ] }
|
568
|
-
field_map = DataMapper::Ext::Array.to_hash(field_map)
|
574
|
+
field_map = Hash[ fields.map { |property| [ property, property.field ] } ]
|
569
575
|
|
570
576
|
records.map do |record|
|
571
577
|
identity_map = nil
|
@@ -621,13 +627,13 @@ module DataMapper
|
|
621
627
|
resource.instance_variable_set(:@_repository, repository)
|
622
628
|
|
623
629
|
if identity_map
|
624
|
-
resource.
|
630
|
+
resource.persistence_state = Resource::PersistenceState::Clean.new(resource) unless resource.persistence_state?
|
625
631
|
|
626
632
|
# defer setting the IdentityMap so second level caches can
|
627
633
|
# record the state of the resource after loaded
|
628
634
|
identity_map[key_values] = resource
|
629
635
|
else
|
630
|
-
resource.
|
636
|
+
resource.persistence_state = Resource::PersistenceState::Immutable.new(resource)
|
631
637
|
end
|
632
638
|
|
633
639
|
resource
|
@@ -637,6 +643,13 @@ module DataMapper
|
|
637
643
|
# @api semipublic
|
638
644
|
attr_reader :base_model
|
639
645
|
|
646
|
+
# The list of writer methods that can be mass-assigned to in #attributes=
|
647
|
+
#
|
648
|
+
# @return [Set]
|
649
|
+
#
|
650
|
+
# @api private
|
651
|
+
attr_reader :allowed_writer_methods
|
652
|
+
|
640
653
|
# @api semipublic
|
641
654
|
def default_repository_name
|
642
655
|
Repository.default_name
|
@@ -760,32 +773,32 @@ module DataMapper
|
|
760
773
|
end
|
761
774
|
end
|
762
775
|
|
776
|
+
# Initialize all foreign key properties established by relationships
|
777
|
+
#
|
778
|
+
# @return [undefined]
|
779
|
+
#
|
780
|
+
# @api private
|
781
|
+
def finalize_relationships
|
782
|
+
relationships(repository_name).each { |relationship| relationship.finalize }
|
783
|
+
end
|
784
|
+
|
785
|
+
# Initialize the list of allowed writer methods
|
786
|
+
#
|
787
|
+
# @return [undefined]
|
788
|
+
#
|
789
|
+
# @api private
|
790
|
+
def finalize_allowed_writer_methods
|
791
|
+
@allowed_writer_methods = public_instance_methods.map { |method| method.to_s }.grep(WRITER_METHOD_REGEXP).to_set
|
792
|
+
@allowed_writer_methods -= INVALID_WRITER_METHODS
|
793
|
+
@allowed_writer_methods.freeze
|
794
|
+
end
|
795
|
+
|
763
796
|
# @api private
|
764
797
|
# TODO: Remove this once appropriate warnings can be added.
|
765
798
|
def assert_valid(force = false) # :nodoc:
|
766
799
|
return if @valid && !force
|
767
800
|
@valid = true
|
768
|
-
|
769
|
-
name = self.name
|
770
|
-
repository_name = self.repository_name
|
771
|
-
|
772
|
-
if properties(repository_name).empty? &&
|
773
|
-
!relationships(repository_name).any? { |(relationship_name, relationship)| relationship.kind_of?(Associations::ManyToOne::Relationship) }
|
774
|
-
raise IncompleteModelError, "#{name} must have at least one property or many to one relationship to be valid"
|
775
|
-
end
|
776
|
-
|
777
|
-
if key(repository_name).empty?
|
778
|
-
raise IncompleteModelError, "#{name} must have a key to be valid"
|
779
|
-
end
|
780
|
-
|
781
|
-
# initialize join models and target keys
|
782
|
-
@relationships.values.each do |relationships|
|
783
|
-
relationships.each do |relationship|
|
784
|
-
relationship.child_key
|
785
|
-
relationship.through if relationship.respond_to?(:through)
|
786
|
-
relationship.via if relationship.respond_to?(:via)
|
787
|
-
end
|
788
|
-
end
|
801
|
+
finalize
|
789
802
|
end
|
790
803
|
|
791
804
|
# Raises an exception if #get receives the wrong number of arguments
|
@@ -807,5 +820,50 @@ module DataMapper
|
|
807
820
|
raise ArgumentError, "The number of arguments for the key is invalid, expected #{expected_key_size} but was #{actual_key_size}"
|
808
821
|
end
|
809
822
|
end
|
823
|
+
|
824
|
+
# Test if the model name is valid
|
825
|
+
#
|
826
|
+
# @return [undefined]
|
827
|
+
#
|
828
|
+
# @api private
|
829
|
+
def assert_valid_name
|
830
|
+
if name.to_s.strip.empty?
|
831
|
+
raise IncompleteModelError, "#{inspect} must have a name"
|
832
|
+
end
|
833
|
+
end
|
834
|
+
|
835
|
+
# Test if the model has properties
|
836
|
+
#
|
837
|
+
# A model may also be valid if it has at least one m:1 relationships which
|
838
|
+
# will add inferred foreign key properties.
|
839
|
+
#
|
840
|
+
# @return [undefined]
|
841
|
+
#
|
842
|
+
# @raise [IncompleteModelError]
|
843
|
+
# raised if the model has no properties
|
844
|
+
#
|
845
|
+
# @api private
|
846
|
+
def assert_valid_properties
|
847
|
+
repository_name = self.repository_name
|
848
|
+
if properties(repository_name).empty? &&
|
849
|
+
!relationships(repository_name).any? { |relationship| relationship.kind_of?(Associations::ManyToOne::Relationship) }
|
850
|
+
raise IncompleteModelError, "#{name} must have at least one property or many to one relationship to be valid"
|
851
|
+
end
|
852
|
+
end
|
853
|
+
|
854
|
+
# Test if the model has a valid key
|
855
|
+
#
|
856
|
+
# @return [undefined]
|
857
|
+
#
|
858
|
+
# @raise [IncompleteModelError]
|
859
|
+
# raised if the model does not have a valid key
|
860
|
+
#
|
861
|
+
# @api private
|
862
|
+
def assert_valid_key
|
863
|
+
if key(repository_name).empty?
|
864
|
+
raise IncompleteModelError, "#{name} must have a key to be valid"
|
865
|
+
end
|
866
|
+
end
|
867
|
+
|
810
868
|
end # module Model
|
811
869
|
end # module DataMapper
|
@@ -6,25 +6,22 @@ module DataMapper
|
|
6
6
|
module Property
|
7
7
|
Model.append_extensions self, DataMapper::Property::Lookup
|
8
8
|
|
9
|
-
extend Chainable
|
10
|
-
|
11
9
|
def self.extended(model)
|
12
10
|
model.instance_variable_set(:@properties, {})
|
13
11
|
model.instance_variable_set(:@field_naming_conventions, {})
|
14
12
|
end
|
15
13
|
|
16
|
-
chainable do
|
17
|
-
def inherited(model)
|
18
|
-
model.instance_variable_set(:@properties, {})
|
19
|
-
model.instance_variable_set(:@field_naming_conventions, @field_naming_conventions.dup)
|
20
14
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
15
|
+
def inherited(model)
|
16
|
+
model.instance_variable_set(:@properties, {})
|
17
|
+
model.instance_variable_set(:@field_naming_conventions, @field_naming_conventions.dup)
|
25
18
|
|
26
|
-
|
19
|
+
@properties.each do |repository_name, properties|
|
20
|
+
model_properties = model.properties(repository_name)
|
21
|
+
properties.each { |property| model_properties << property }
|
27
22
|
end
|
23
|
+
|
24
|
+
super
|
28
25
|
end
|
29
26
|
|
30
27
|
# Defines a Property on the Resource
|
@@ -64,13 +61,16 @@ module DataMapper
|
|
64
61
|
|
65
62
|
# Add property to the other mappings as well if this is for the default
|
66
63
|
# repository.
|
64
|
+
|
67
65
|
if repository_name == default_repository_name
|
68
|
-
DataMapper::Ext::Hash.except(@properties, default_repository_name)
|
66
|
+
other_repository_properties = DataMapper::Ext::Hash.except(@properties, default_repository_name)
|
67
|
+
|
68
|
+
other_repository_properties.each do |other_repository_name, properties|
|
69
69
|
next if properties.named?(name)
|
70
70
|
|
71
71
|
# make sure the property is created within the correct repository scope
|
72
72
|
DataMapper.repository(other_repository_name) do
|
73
|
-
properties << klass.new(self, name, options
|
73
|
+
properties << klass.new(self, name, options)
|
74
74
|
end
|
75
75
|
end
|
76
76
|
end
|
@@ -175,11 +175,10 @@ module DataMapper
|
|
175
175
|
|
176
176
|
# @api private
|
177
177
|
def key_conditions(repository, key)
|
178
|
-
|
179
|
-
DataMapper::Ext::Array.to_hash(conditions)
|
178
|
+
Hash[ self.key(repository.name).zip(key.nil? ? [] : key) ]
|
180
179
|
end
|
181
180
|
|
182
|
-
|
181
|
+
private
|
183
182
|
|
184
183
|
# Defines the anonymous module that is used to add properties.
|
185
184
|
# Using a single module here prevents having a very large number
|
@@ -207,7 +206,7 @@ module DataMapper
|
|
207
206
|
def #{name}
|
208
207
|
return #{instance_variable_name} if defined?(#{instance_variable_name})
|
209
208
|
property = properties[#{name.inspect}]
|
210
|
-
#{instance_variable_name} = property ?
|
209
|
+
#{instance_variable_name} = property ? persistence_state.get(property) : nil
|
211
210
|
end
|
212
211
|
RUBY
|
213
212
|
|
@@ -235,21 +234,19 @@ module DataMapper
|
|
235
234
|
#{writer_visibility}
|
236
235
|
def #{writer_name}(value)
|
237
236
|
property = properties[#{name.inspect}]
|
238
|
-
self.
|
239
|
-
|
237
|
+
self.persistence_state = persistence_state.set(property, value)
|
238
|
+
persistence_state.get(property)
|
240
239
|
end
|
241
240
|
RUBY
|
242
241
|
end
|
243
242
|
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
return property
|
249
|
-
end
|
250
|
-
|
251
|
-
super
|
243
|
+
# @api public
|
244
|
+
def method_missing(method, *args, &block)
|
245
|
+
if property = properties(repository_name)[method]
|
246
|
+
return property
|
252
247
|
end
|
248
|
+
|
249
|
+
super
|
253
250
|
end
|
254
251
|
end # module Property
|
255
252
|
end # module Model
|