dm-core 1.0.0.rc2 → 1.0.0.rc3
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -1
- data/LICENSE +1 -1
- data/README.rdoc +1 -1
- data/Rakefile +3 -4
- data/VERSION +1 -1
- data/dm-core.gemspec +7 -5
- data/lib/dm-core.rb +44 -0
- data/lib/dm-core/adapters.rb +1 -1
- data/lib/dm-core/adapters/abstract_adapter.rb +16 -0
- data/lib/dm-core/collection.rb +2 -2
- data/lib/dm-core/model.rb +64 -53
- data/lib/dm-core/model/property.rb +14 -6
- data/lib/dm-core/model/relationship.rb +10 -18
- data/lib/dm-core/property.rb +10 -10
- data/lib/dm-core/query.rb +8 -18
- data/lib/dm-core/resource.rb +3 -11
- data/lib/dm-core/resource/state.rb +13 -16
- data/lib/dm-core/resource/state/dirty.rb +11 -1
- data/lib/dm-core/resource/state/transient.rb +9 -1
- data/lib/dm-core/spec/lib/adapter_helpers.rb +5 -0
- data/lib/dm-core/spec/shared/adapter_spec.rb +2 -0
- data/lib/dm-core/spec/shared/resource_spec.rb +0 -31
- data/lib/dm-core/version.rb +1 -1
- data/spec/public/associations/many_to_many/read_multiple_join_spec.rb +2 -0
- data/spec/public/associations/many_to_many_spec.rb +2 -1
- data/spec/public/associations/many_to_one_spec.rb +1 -0
- data/spec/public/associations/many_to_one_with_boolean_cpk_spec.rb +1 -0
- data/spec/public/associations/one_to_many_spec.rb +2 -0
- data/spec/public/associations/one_to_one_spec.rb +2 -0
- data/spec/public/associations/one_to_one_with_boolean_cpk_spec.rb +1 -0
- data/spec/public/collection_spec.rb +2 -0
- data/spec/public/finalize_spec.rb +34 -0
- data/spec/public/model/hook_spec.rb +1 -0
- data/spec/public/model/property_spec.rb +1 -0
- data/spec/public/model/relationship_spec.rb +22 -0
- data/spec/public/model_spec.rb +138 -3
- data/spec/public/property/discriminator_spec.rb +1 -0
- data/spec/public/property/object_spec.rb +1 -0
- data/spec/public/property_spec.rb +13 -4
- data/spec/public/resource_spec.rb +1 -0
- data/spec/public/sel_spec.rb +2 -0
- data/spec/public/shared/collection_shared_spec.rb +0 -45
- data/spec/public/shared/finder_shared_spec.rb +110 -0
- data/spec/public/shared/property_shared_spec.rb +1 -1
- data/spec/rcov.opts +1 -1
- data/spec/semipublic/associations/many_to_many_spec.rb +3 -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/associations/relationship_spec.rb +6 -0
- data/spec/semipublic/query/conditions/comparison_spec.rb +3 -0
- data/spec/semipublic/query/conditions/operation_spec.rb +1 -0
- data/spec/semipublic/query/path_spec.rb +2 -0
- data/spec/semipublic/query_spec.rb +2 -3
- data/spec/semipublic/resource/state/clean_spec.rb +2 -1
- data/spec/semipublic/resource/state/deleted_spec.rb +2 -1
- data/spec/semipublic/resource/state/dirty_spec.rb +42 -20
- data/spec/semipublic/resource/state/immutable_spec.rb +7 -1
- data/spec/semipublic/resource/state/transient_spec.rb +69 -40
- data/spec/semipublic/resource/state_spec.rb +72 -66
- data/spec/semipublic/shared/property_shared_spec.rb +1 -0
- data/spec/semipublic/shared/resource_shared_spec.rb +1 -0
- data/spec/spec_helper.rb +0 -10
- data/tasks/spec.rake +3 -0
- metadata +9 -7
data/Gemfile
CHANGED
data/LICENSE
CHANGED
data/README.rdoc
CHANGED
data/Rakefile
CHANGED
@@ -10,17 +10,16 @@ begin
|
|
10
10
|
gem.summary = 'An Object/Relational Mapper for Ruby'
|
11
11
|
gem.description = 'Faster, Better, Simpler.'
|
12
12
|
gem.email = 'dan.kubb@gmail.com'
|
13
|
-
gem.homepage = 'http://github.com/datamapper
|
13
|
+
gem.homepage = 'http://github.com/datamapper/%s' % gem.name
|
14
14
|
gem.authors = [ 'Dan Kubb' ]
|
15
15
|
|
16
16
|
gem.rubyforge_project = 'datamapper'
|
17
17
|
|
18
|
-
gem.add_dependency 'extlib',
|
19
|
-
gem.add_dependency 'addressable',
|
18
|
+
gem.add_dependency 'extlib', '~> 0.9.15'
|
19
|
+
gem.add_dependency 'addressable', '~> 2.1'
|
20
20
|
|
21
21
|
gem.add_development_dependency 'rspec', '~> 1.3'
|
22
22
|
gem.add_development_dependency 'jeweler', '~> 1.4'
|
23
|
-
|
24
23
|
end
|
25
24
|
|
26
25
|
Jeweler::GemcutterTasks.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.0.
|
1
|
+
1.0.0.rc3
|
data/dm-core.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{dm-core}
|
8
|
-
s.version = "1.0.0.
|
8
|
+
s.version = "1.0.0.rc3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Dan Kubb"]
|
12
|
-
s.date = %q{2010-05-
|
12
|
+
s.date = %q{2010-05-27}
|
13
13
|
s.description = %q{Faster, Better, Simpler.}
|
14
14
|
s.email = %q{dan.kubb@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -126,6 +126,7 @@ Gem::Specification.new do |s|
|
|
126
126
|
"spec/public/associations/one_to_one_spec.rb",
|
127
127
|
"spec/public/associations/one_to_one_with_boolean_cpk_spec.rb",
|
128
128
|
"spec/public/collection_spec.rb",
|
129
|
+
"spec/public/finalize_spec.rb",
|
129
130
|
"spec/public/model/hook_spec.rb",
|
130
131
|
"spec/public/model/property_spec.rb",
|
131
132
|
"spec/public/model/relationship_spec.rb",
|
@@ -227,6 +228,7 @@ Gem::Specification.new do |s|
|
|
227
228
|
"spec/public/associations/one_to_one_spec.rb",
|
228
229
|
"spec/public/associations/one_to_one_with_boolean_cpk_spec.rb",
|
229
230
|
"spec/public/collection_spec.rb",
|
231
|
+
"spec/public/finalize_spec.rb",
|
230
232
|
"spec/public/model/hook_spec.rb",
|
231
233
|
"spec/public/model/property_spec.rb",
|
232
234
|
"spec/public/model/relationship_spec.rb",
|
@@ -310,18 +312,18 @@ Gem::Specification.new do |s|
|
|
310
312
|
s.specification_version = 3
|
311
313
|
|
312
314
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
313
|
-
s.add_runtime_dependency(%q<extlib>, ["~> 0.9.
|
315
|
+
s.add_runtime_dependency(%q<extlib>, ["~> 0.9.15"])
|
314
316
|
s.add_runtime_dependency(%q<addressable>, ["~> 2.1"])
|
315
317
|
s.add_development_dependency(%q<rspec>, ["~> 1.3"])
|
316
318
|
s.add_development_dependency(%q<jeweler>, ["~> 1.4"])
|
317
319
|
else
|
318
|
-
s.add_dependency(%q<extlib>, ["~> 0.9.
|
320
|
+
s.add_dependency(%q<extlib>, ["~> 0.9.15"])
|
319
321
|
s.add_dependency(%q<addressable>, ["~> 2.1"])
|
320
322
|
s.add_dependency(%q<rspec>, ["~> 1.3"])
|
321
323
|
s.add_dependency(%q<jeweler>, ["~> 1.4"])
|
322
324
|
end
|
323
325
|
else
|
324
|
-
s.add_dependency(%q<extlib>, ["~> 0.9.
|
326
|
+
s.add_dependency(%q<extlib>, ["~> 0.9.15"])
|
325
327
|
s.add_dependency(%q<addressable>, ["~> 2.1"])
|
326
328
|
s.add_dependency(%q<rspec>, ["~> 1.3"])
|
327
329
|
s.add_dependency(%q<jeweler>, ["~> 1.4"])
|
data/lib/dm-core.rb
CHANGED
@@ -285,4 +285,48 @@ module DataMapper
|
|
285
285
|
current_repository
|
286
286
|
end
|
287
287
|
end
|
288
|
+
|
289
|
+
# Perform necessary steps to finalize DataMapper for the current repository
|
290
|
+
#
|
291
|
+
# This method should be called after loading all models and plugins.
|
292
|
+
#
|
293
|
+
# It ensures foreign key properties and anonymous join models are created.
|
294
|
+
# These are otherwise lazily declared, which can lead to unexpected errors.
|
295
|
+
# It also performs basic validity checking of the DataMapper models.
|
296
|
+
#
|
297
|
+
# @return [DataMapper] The DataMapper module
|
298
|
+
#
|
299
|
+
# @api public
|
300
|
+
def self.finalize
|
301
|
+
Model.descendants.each do |model|
|
302
|
+
finalize_model(model)
|
303
|
+
end
|
304
|
+
self
|
305
|
+
end
|
306
|
+
|
307
|
+
private
|
308
|
+
# @api private
|
309
|
+
def self.finalize_model(model)
|
310
|
+
name = model.name
|
311
|
+
repository_name = model.repository_name
|
312
|
+
relationships = model.relationships(repository_name).values
|
313
|
+
|
314
|
+
if model.properties(repository_name).empty? &&
|
315
|
+
!relationships.any? { |relationship| relationship.kind_of?(Associations::ManyToOne::Relationship) }
|
316
|
+
raise IncompleteModelError, "#{name} must have at least one property or many to one relationship to be valid"
|
317
|
+
end
|
318
|
+
|
319
|
+
if model.key(repository_name).empty?
|
320
|
+
raise IncompleteModelError, "#{name} must have a key to be valid"
|
321
|
+
end
|
322
|
+
|
323
|
+
|
324
|
+
# initialize join models and target keys
|
325
|
+
relationships.each do |relationship|
|
326
|
+
relationship.child_key
|
327
|
+
relationship.through if relationship.respond_to?(:through)
|
328
|
+
relationship.via if relationship.respond_to?(:via)
|
329
|
+
end
|
330
|
+
|
331
|
+
end
|
288
332
|
end
|
data/lib/dm-core/adapters.rb
CHANGED
@@ -18,6 +18,22 @@ module DataMapper
|
|
18
18
|
|
19
19
|
equalize :name, :options, :resource_naming_convention, :field_naming_convention
|
20
20
|
|
21
|
+
# @api semipublic
|
22
|
+
def self.descendants
|
23
|
+
@descendants ||= Set.new
|
24
|
+
end
|
25
|
+
|
26
|
+
# @api private
|
27
|
+
def self.inherited(subclass)
|
28
|
+
add_descendant(subclass)
|
29
|
+
end
|
30
|
+
|
31
|
+
# @api private
|
32
|
+
def self.add_descendant(subclass)
|
33
|
+
descendants << subclass
|
34
|
+
superclass.add_descendant(subclass) if superclass.respond_to?(:add_descendant)
|
35
|
+
end
|
36
|
+
|
21
37
|
# Adapter name
|
22
38
|
#
|
23
39
|
# @example
|
data/lib/dm-core/collection.rb
CHANGED
@@ -1441,7 +1441,7 @@ module DataMapper
|
|
1441
1441
|
def method_missing(method, *args, &block)
|
1442
1442
|
relationships = self.relationships
|
1443
1443
|
|
1444
|
-
if model.
|
1444
|
+
if model.respond_to?(method)
|
1445
1445
|
delegate_to_model(method, *args, &block)
|
1446
1446
|
elsif relationship = relationships[method] || relationships[method.to_s.singularize.to_sym]
|
1447
1447
|
delegate_to_relationship(relationship, *args)
|
@@ -1463,7 +1463,7 @@ module DataMapper
|
|
1463
1463
|
# @api private
|
1464
1464
|
def delegate_to_model(method, *args, &block)
|
1465
1465
|
model = self.model
|
1466
|
-
model.
|
1466
|
+
model.send(:with_scope, query) do
|
1467
1467
|
model.send(method, *args, &block)
|
1468
1468
|
end
|
1469
1469
|
end
|
data/lib/dm-core/model.rb
CHANGED
@@ -7,6 +7,8 @@ module DataMapper
|
|
7
7
|
module Model
|
8
8
|
extend Chainable
|
9
9
|
|
10
|
+
include Enumerable
|
11
|
+
|
10
12
|
# Creates a new Model class with default_storage_name +storage_name+
|
11
13
|
#
|
12
14
|
# If a block is passed, it will be eval'd in the context of the new Model
|
@@ -305,17 +307,23 @@ module DataMapper
|
|
305
307
|
all.at(*args)
|
306
308
|
end
|
307
309
|
|
310
|
+
def fetch(*args, &block)
|
311
|
+
all.fetch(*args, &block)
|
312
|
+
end
|
313
|
+
|
314
|
+
def values_at(*args)
|
315
|
+
all.values_at(*args)
|
316
|
+
end
|
317
|
+
|
308
318
|
def reverse
|
309
319
|
all.reverse
|
310
320
|
end
|
311
321
|
|
312
|
-
|
313
|
-
|
314
|
-
|
322
|
+
def each(&block)
|
323
|
+
all.each(&block)
|
324
|
+
self
|
315
325
|
end
|
316
326
|
|
317
|
-
alias to_a entries
|
318
|
-
|
319
327
|
# Find a set of records matching an optional set of conditions. Additionally,
|
320
328
|
# specify the order that the records are return.
|
321
329
|
#
|
@@ -444,22 +452,6 @@ module DataMapper
|
|
444
452
|
first(conditions) || create(conditions.merge(attributes))
|
445
453
|
end
|
446
454
|
|
447
|
-
# Initializes an instance of Resource with the given attributes
|
448
|
-
#
|
449
|
-
# @param [Hash(Symbol => Object)] attributes
|
450
|
-
# hash of attributes to set
|
451
|
-
#
|
452
|
-
# @return [Resource]
|
453
|
-
# the newly initialized Resource instance
|
454
|
-
#
|
455
|
-
# @api public
|
456
|
-
chainable do
|
457
|
-
def new(*args, &block)
|
458
|
-
assert_valid
|
459
|
-
super
|
460
|
-
end
|
461
|
-
end
|
462
|
-
|
463
455
|
# Create a Resource
|
464
456
|
#
|
465
457
|
# @param [Hash(Symbol => Object)] attributes
|
@@ -486,6 +478,56 @@ module DataMapper
|
|
486
478
|
_create(attributes, false)
|
487
479
|
end
|
488
480
|
|
481
|
+
# Update every Resource
|
482
|
+
#
|
483
|
+
# Person.update(:allow_beer => true)
|
484
|
+
#
|
485
|
+
# @param [Hash] attributes
|
486
|
+
# attributes to update with
|
487
|
+
#
|
488
|
+
# @return [Boolean]
|
489
|
+
# true if the resources were successfully updated
|
490
|
+
#
|
491
|
+
# @api public
|
492
|
+
def update(attributes)
|
493
|
+
all.update(attributes)
|
494
|
+
end
|
495
|
+
|
496
|
+
# Update every Resource, bypassing validations
|
497
|
+
#
|
498
|
+
# Person.update!(:allow_beer => true)
|
499
|
+
#
|
500
|
+
# @param [Hash] attributes
|
501
|
+
# attributes to update with
|
502
|
+
#
|
503
|
+
# @return [Boolean]
|
504
|
+
# true if the resources were successfully updated
|
505
|
+
#
|
506
|
+
# @api public
|
507
|
+
def update!(attributes)
|
508
|
+
all.update!(attributes)
|
509
|
+
end
|
510
|
+
|
511
|
+
# Remove all Resources from the repository
|
512
|
+
#
|
513
|
+
# @return [Boolean]
|
514
|
+
# true if the resources were successfully destroyed
|
515
|
+
#
|
516
|
+
# @api public
|
517
|
+
def destroy
|
518
|
+
all.destroy
|
519
|
+
end
|
520
|
+
|
521
|
+
# Remove all Resources from the repository, bypassing validation
|
522
|
+
#
|
523
|
+
# @return [Boolean]
|
524
|
+
# true if the resources were successfully destroyed
|
525
|
+
#
|
526
|
+
# @api public
|
527
|
+
def destroy!
|
528
|
+
all.destroy!
|
529
|
+
end
|
530
|
+
|
489
531
|
# Copy a set of records from one repository to another.
|
490
532
|
#
|
491
533
|
# @param [String] source_repository_name
|
@@ -668,16 +710,6 @@ module DataMapper
|
|
668
710
|
[ repository ].to_set + @properties.keys.map { |repository_name| DataMapper.repository(repository_name) }
|
669
711
|
end
|
670
712
|
|
671
|
-
# @api private
|
672
|
-
def model_method_defined?(method)
|
673
|
-
model_methods.include?(method.to_s)
|
674
|
-
end
|
675
|
-
|
676
|
-
# @api private
|
677
|
-
def resource_method_defined?(method)
|
678
|
-
resource_methods.include?(method.to_s)
|
679
|
-
end
|
680
|
-
|
681
713
|
private
|
682
714
|
|
683
715
|
# @api private
|
@@ -748,6 +780,7 @@ module DataMapper
|
|
748
780
|
end
|
749
781
|
|
750
782
|
# @api private
|
783
|
+
# TODO: Remove this once appropriate warnings can be added.
|
751
784
|
def assert_valid(force = false) # :nodoc:
|
752
785
|
return if @valid && !force
|
753
786
|
@valid = true
|
@@ -774,28 +807,6 @@ module DataMapper
|
|
774
807
|
end
|
775
808
|
end
|
776
809
|
|
777
|
-
# @api private
|
778
|
-
def model_methods
|
779
|
-
@model_methods ||= ancestor_instance_methods { |mod| mod.singleton_class }
|
780
|
-
end
|
781
|
-
|
782
|
-
# @api private
|
783
|
-
def resource_methods
|
784
|
-
@resource_methods ||= ancestor_instance_methods { |mod| mod }
|
785
|
-
end
|
786
|
-
|
787
|
-
# @api private
|
788
|
-
def ancestor_instance_methods
|
789
|
-
methods = Set.new
|
790
|
-
|
791
|
-
ancestors.each do |mod|
|
792
|
-
next unless mod <= DataMapper::Resource
|
793
|
-
methods.merge(yield(mod).instance_methods(false).map { |method| method.to_s })
|
794
|
-
end
|
795
|
-
|
796
|
-
methods
|
797
|
-
end
|
798
|
-
|
799
810
|
# Raises an exception if #get receives the wrong number of arguments
|
800
811
|
#
|
801
812
|
# @param [Array] key
|
@@ -222,9 +222,8 @@ module DataMapper
|
|
222
222
|
name = property.name.to_s
|
223
223
|
reader_visibility = property.reader_visibility
|
224
224
|
instance_variable_name = property.instance_variable_name
|
225
|
-
primitive = property.primitive
|
226
225
|
|
227
|
-
unless
|
226
|
+
unless reserved_method?(name)
|
228
227
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
229
228
|
chainable do
|
230
229
|
#{reader_visibility}
|
@@ -239,10 +238,14 @@ module DataMapper
|
|
239
238
|
|
240
239
|
boolean_reader_name = "#{name}?"
|
241
240
|
|
242
|
-
if
|
241
|
+
if property.kind_of?(DataMapper::Property::Boolean) && !reserved_method?(boolean_reader_name)
|
243
242
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
244
|
-
|
245
|
-
|
243
|
+
chainable do
|
244
|
+
#{reader_visibility}
|
245
|
+
def #{boolean_reader_name}
|
246
|
+
#{name}
|
247
|
+
end
|
248
|
+
end
|
246
249
|
RUBY
|
247
250
|
end
|
248
251
|
end
|
@@ -256,7 +259,7 @@ module DataMapper
|
|
256
259
|
|
257
260
|
writer_name = "#{name}="
|
258
261
|
|
259
|
-
return if
|
262
|
+
return if reserved_method?(writer_name)
|
260
263
|
|
261
264
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
262
265
|
chainable do
|
@@ -270,6 +273,11 @@ module DataMapper
|
|
270
273
|
RUBY
|
271
274
|
end
|
272
275
|
|
276
|
+
# @api private
|
277
|
+
def reserved_method?(name)
|
278
|
+
method_defined?(name) && !%w[ id type ].include?(name)
|
279
|
+
end
|
280
|
+
|
273
281
|
chainable do
|
274
282
|
# @api public
|
275
283
|
def method_missing(method, *args, &block)
|
@@ -81,17 +81,13 @@ module DataMapper
|
|
81
81
|
# cardinality that defines the association type and constraints
|
82
82
|
# @param name [Symbol]
|
83
83
|
# the name that the association will be referenced by
|
84
|
-
# @param
|
85
|
-
# the target model of the relationship
|
86
|
-
# @param opts [Hash]
|
87
|
-
# an options hash
|
84
|
+
# @param *args [Model, Hash] model and/or options hash
|
88
85
|
#
|
89
|
-
# @option :through[Symbol]
|
86
|
+
# @option *args :through[Symbol] A association that this join should go through to form
|
90
87
|
# a many-to-many association
|
91
|
-
# @option :model[Model, String] The name of the class to associate with, if omitted
|
88
|
+
# @option *args :model[Model, String] The name of the class to associate with, if omitted
|
92
89
|
# then the association name is assumed to match the class name
|
93
|
-
# @option :repository[Symbol]
|
94
|
-
# name of child model repository
|
90
|
+
# @option *args :repository[Symbol] name of child model repository
|
95
91
|
#
|
96
92
|
# @return [Association::Relationship] the relationship that was
|
97
93
|
# created to reflect either a one-to-one, one-to-many or many-to-many
|
@@ -148,15 +144,11 @@ module DataMapper
|
|
148
144
|
#
|
149
145
|
# @param name [Symbol]
|
150
146
|
# the name that the association will be referenced by
|
151
|
-
# @param
|
152
|
-
# the target model of the relationship
|
153
|
-
# @param opts [Hash]
|
154
|
-
# an options hash
|
147
|
+
# @param *args [Model, Hash] model and/or options hash
|
155
148
|
#
|
156
|
-
# @option :model[Model, String] The name of the class to associate with, if omitted
|
149
|
+
# @option *args :model[Model, String] The name of the class to associate with, if omitted
|
157
150
|
# then the association name is assumed to match the class name
|
158
|
-
# @option :repository[Symbol]
|
159
|
-
# name of child model repository
|
151
|
+
# @option *args :repository[Symbol] name of child model repository
|
160
152
|
#
|
161
153
|
# @return [Association::Relationship] The association created
|
162
154
|
# should not be accessed directly
|
@@ -311,7 +303,7 @@ module DataMapper
|
|
311
303
|
# :target_key (will mean something different for each relationship)
|
312
304
|
|
313
305
|
[ :child_key, :parent_key ].each do |key|
|
314
|
-
if options.key?(key)
|
306
|
+
if options.key?(key)
|
315
307
|
options[key] = Array(options[key])
|
316
308
|
end
|
317
309
|
end
|
@@ -328,7 +320,7 @@ module DataMapper
|
|
328
320
|
name = relationship.name
|
329
321
|
reader_name = name.to_s
|
330
322
|
|
331
|
-
return if
|
323
|
+
return if method_defined?(reader_name)
|
332
324
|
|
333
325
|
reader_visibility = relationship.reader_visibility
|
334
326
|
|
@@ -355,7 +347,7 @@ module DataMapper
|
|
355
347
|
name = relationship.name
|
356
348
|
writer_name = "#{name}="
|
357
349
|
|
358
|
-
return if
|
350
|
+
return if method_defined?(writer_name)
|
359
351
|
|
360
352
|
writer_visibility = relationship.writer_visibility
|
361
353
|
|