sam-dm-core 0.9.6 → 0.9.7
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest.txt +5 -0
- data/QUICKLINKS +1 -2
- data/Rakefile +3 -3
- data/SPECS +9 -10
- data/lib/dm-core.rb +15 -22
- data/lib/dm-core/adapters.rb +18 -0
- data/lib/dm-core/adapters/abstract_adapter.rb +17 -10
- data/lib/dm-core/adapters/data_objects_adapter.rb +18 -16
- data/lib/dm-core/adapters/mysql_adapter.rb +1 -1
- data/lib/dm-core/adapters/postgres_adapter.rb +2 -2
- data/lib/dm-core/adapters/sqlite3_adapter.rb +1 -1
- data/lib/dm-core/associations.rb +3 -2
- data/lib/dm-core/associations/many_to_many.rb +2 -2
- data/lib/dm-core/associations/many_to_one.rb +1 -1
- data/lib/dm-core/associations/one_to_many.rb +13 -7
- data/lib/dm-core/associations/relationship.rb +20 -15
- data/lib/dm-core/auto_migrations.rb +4 -12
- data/lib/dm-core/collection.rb +9 -5
- data/lib/dm-core/dependency_queue.rb +2 -1
- data/lib/dm-core/identity_map.rb +3 -6
- data/lib/dm-core/model.rb +44 -27
- data/lib/dm-core/property.rb +3 -13
- data/lib/dm-core/property_set.rb +29 -22
- data/lib/dm-core/query.rb +49 -47
- data/lib/dm-core/repository.rb +3 -3
- data/lib/dm-core/resource.rb +12 -12
- data/lib/dm-core/scope.rb +7 -7
- data/lib/dm-core/support/kernel.rb +6 -2
- data/lib/dm-core/transaction.rb +7 -7
- data/lib/dm-core/version.rb +1 -1
- data/script/performance.rb +109 -30
- data/script/profile.rb +2 -2
- data/spec/integration/association_spec.rb +13 -1
- data/spec/integration/associations/one_to_many_spec.rb +40 -3
- data/spec/integration/auto_migrations_spec.rb +16 -1
- data/spec/integration/dependency_queue_spec.rb +0 -12
- data/spec/integration/postgres_adapter_spec.rb +1 -1
- data/spec/integration/property_spec.rb +4 -4
- data/spec/integration/resource_spec.rb +6 -0
- data/spec/integration/sti_spec.rb +22 -0
- data/spec/integration/strategic_eager_loading_spec.rb +21 -6
- data/spec/integration/type_spec.rb +1 -1
- data/spec/lib/model_loader.rb +10 -1
- data/spec/models/zoo.rb +1 -0
- data/spec/spec_helper.rb +3 -2
- data/spec/unit/adapters/data_objects_adapter_spec.rb +3 -3
- data/spec/unit/associations/many_to_many_spec.rb +16 -1
- data/spec/unit/associations/many_to_one_spec.rb +9 -2
- data/spec/unit/model_spec.rb +12 -30
- data/spec/unit/property_set_spec.rb +8 -1
- data/spec/unit/query_spec.rb +41 -0
- data/spec/unit/resource_spec.rb +27 -4
- data/spec/unit/transaction_spec.rb +13 -13
- data/tasks/ci.rb +4 -36
- data/tasks/dm.rb +3 -3
- metadata +7 -16
data/Manifest.txt
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
.autotest
|
2
|
+
.gitignore
|
2
3
|
CONTRIBUTING
|
3
4
|
FAQ
|
4
5
|
History.txt
|
@@ -9,10 +10,12 @@ README.txt
|
|
9
10
|
Rakefile
|
10
11
|
SPECS
|
11
12
|
TODO
|
13
|
+
dm-core.gemspec
|
12
14
|
lib/dm-core.rb
|
13
15
|
lib/dm-core/adapters.rb
|
14
16
|
lib/dm-core/adapters/abstract_adapter.rb
|
15
17
|
lib/dm-core/adapters/data_objects_adapter.rb
|
18
|
+
lib/dm-core/adapters/in_memory_adapter.rb
|
16
19
|
lib/dm-core/adapters/mysql_adapter.rb
|
17
20
|
lib/dm-core/adapters/postgres_adapter.rb
|
18
21
|
lib/dm-core/adapters/sqlite3_adapter.rb
|
@@ -86,6 +89,7 @@ spec/lib/logging_helper.rb
|
|
86
89
|
spec/lib/mock_adapter.rb
|
87
90
|
spec/lib/model_loader.rb
|
88
91
|
spec/lib/publicize_methods.rb
|
92
|
+
spec/models/content.rb
|
89
93
|
spec/models/vehicles.rb
|
90
94
|
spec/models/zoo.rb
|
91
95
|
spec/spec.opts
|
@@ -93,6 +97,7 @@ spec/spec_helper.rb
|
|
93
97
|
spec/unit/adapters/abstract_adapter_spec.rb
|
94
98
|
spec/unit/adapters/adapter_shared_spec.rb
|
95
99
|
spec/unit/adapters/data_objects_adapter_spec.rb
|
100
|
+
spec/unit/adapters/in_memory_adapter_spec.rb
|
96
101
|
spec/unit/adapters/postgres_adapter_spec.rb
|
97
102
|
spec/unit/associations/many_to_many_spec.rb
|
98
103
|
spec/unit/associations/many_to_one_spec.rb
|
data/QUICKLINKS
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
= Quick Links
|
2
2
|
|
3
3
|
* Setup and Configuration - DataMapper
|
4
|
-
* Finders and CRUD -
|
4
|
+
* Finders and CRUD -
|
5
5
|
* Properties - DataMapper::Property
|
6
6
|
* FAQ[link:/files/FAQ.html]
|
7
7
|
* Contact Us
|
@@ -9,4 +9,3 @@
|
|
9
9
|
* Bug Reports - http://wm.lighthouseapp.com/projects/4819-datamapper/overview
|
10
10
|
* IRC Channel - <tt>##datamapper</tt> on irc.freenode.net
|
11
11
|
* Mailing List - http://groups.google.com/group/datamapper/
|
12
|
-
|
data/Rakefile
CHANGED
@@ -13,9 +13,9 @@ AUTHOR = "Sam Smoot"
|
|
13
13
|
EMAIL = "ssmoot@gmail.com"
|
14
14
|
GEM_NAME = "dm-core"
|
15
15
|
GEM_VERSION = DataMapper::VERSION
|
16
|
-
GEM_DEPENDENCIES = ["data_objects", "
|
17
|
-
["
|
18
|
-
|
16
|
+
GEM_DEPENDENCIES = ["data_objects", "~>0.9.9"],
|
17
|
+
["extlib", "~>0.9.9"],
|
18
|
+
["addressable", "~>2.0.1"]
|
19
19
|
|
20
20
|
PROJECT_NAME = "datamapper"
|
21
21
|
PROJECT_DESCRIPTION = "Faster, Better, Simpler."
|
data/SPECS
CHANGED
@@ -2,14 +2,14 @@ Reading Specs
|
|
2
2
|
=============
|
3
3
|
|
4
4
|
Blah blah blah...
|
5
|
-
|
5
|
+
|
6
6
|
Writing Specs
|
7
7
|
=============
|
8
8
|
|
9
9
|
Here are some general dos and don'ts
|
10
|
-
|
10
|
+
|
11
11
|
= DO:
|
12
|
-
|
12
|
+
|
13
13
|
* Write more specs for error conditions than clean conditions.
|
14
14
|
* Write specs with readability in mind. Somebody knew to DataMapper should be
|
15
15
|
able to read specs to learn how something works.
|
@@ -18,14 +18,14 @@ Writing Specs
|
|
18
18
|
* Limit a describe block to 10 - 15 examples.
|
19
19
|
* Group specs by method being tested. (See the 'Ordering Specs' section)
|
20
20
|
* Use custom matchers.
|
21
|
-
|
21
|
+
|
22
22
|
= DON'T:
|
23
|
-
|
23
|
+
|
24
24
|
* Spec more than one unit of functionality in an example. An example should be
|
25
25
|
as short as possible (while still remaining readable).
|
26
26
|
* Spec implementation. Refactoring code should not break specs.
|
27
27
|
* Declare models in the spec file.
|
28
|
-
|
28
|
+
|
29
29
|
And a final do: Do go against the guidelines if your best judgement tells you
|
30
30
|
to. These are just guidelines and are obviously not fast rules.
|
31
31
|
|
@@ -39,7 +39,7 @@ Models
|
|
39
39
|
few simple metaphors, such as a zoo, a blog implementation, etc... Following
|
40
40
|
metaphors makes it easier for a reader to guess what is going on with respect
|
41
41
|
to the models.
|
42
|
-
|
42
|
+
|
43
43
|
The second reason is to allow the spec environment to be as pristine as
|
44
44
|
possible going into an example. Models being loaded from the model directory
|
45
45
|
are tracked and reloaded before each example. Any changes that might be made
|
@@ -51,13 +51,12 @@ Mocks and Stubs
|
|
51
51
|
Obviously, mocks and stubs are a powerful feature when it comes to BDD;
|
52
52
|
however, remember that you are writing specs for behavior and NOT
|
53
53
|
implementation.
|
54
|
-
|
54
|
+
|
55
55
|
Ordering Specs
|
56
56
|
==============
|
57
57
|
|
58
58
|
Specs aren't much use if nobody can find where anything is, so keeping specs
|
59
59
|
well organized is critical. Currently, we are trying out the following
|
60
60
|
structure:
|
61
|
-
|
61
|
+
|
62
62
|
* List guidelines here...
|
63
|
-
|
data/lib/dm-core.rb
CHANGED
@@ -11,22 +11,22 @@
|
|
11
11
|
|
12
12
|
require 'date'
|
13
13
|
require 'pathname'
|
14
|
+
require 'rubygems'
|
14
15
|
require 'set'
|
15
16
|
require 'time'
|
16
17
|
require 'yaml'
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
gem 'addressable', '>=1.0.4'
|
19
|
+
gem 'addressable', '~>2.0.1'
|
21
20
|
require 'addressable/uri'
|
22
21
|
|
23
|
-
gem 'extlib', '
|
22
|
+
gem 'extlib', '~>0.9.9'
|
24
23
|
require 'extlib'
|
25
|
-
require
|
24
|
+
require 'extlib/inflection'
|
26
25
|
|
27
26
|
begin
|
27
|
+
gem 'fastthread', '~>1.0.1'
|
28
28
|
require 'fastthread'
|
29
|
-
rescue LoadError
|
29
|
+
rescue Gem::LoadError
|
30
30
|
# fastthread not installed
|
31
31
|
end
|
32
32
|
|
@@ -133,8 +133,8 @@ module DataMapper
|
|
133
133
|
case uri_or_options
|
134
134
|
when Hash
|
135
135
|
adapter_name = uri_or_options[:adapter].to_s
|
136
|
-
when String, Addressable::URI
|
137
|
-
uri_or_options =
|
136
|
+
when String, DataObjects::URI, Addressable::URI
|
137
|
+
uri_or_options = DataObjects::URI.parse(uri_or_options) if uri_or_options.kind_of?(String)
|
138
138
|
adapter_name = uri_or_options.scheme
|
139
139
|
end
|
140
140
|
|
@@ -169,26 +169,19 @@ module DataMapper
|
|
169
169
|
# @param [Symbol] args the name of a repository to act within or return, :default is default
|
170
170
|
# @yield [Proc] (optional) block to execute within the context of the named repository
|
171
171
|
# @demo spec/integration/repository_spec.rb
|
172
|
-
def self.repository(
|
173
|
-
if args.size > 1
|
174
|
-
raise ArgumentError, "Can only pass in one optional argument, but passed in #{args.size} arguments", caller
|
175
|
-
end
|
176
|
-
|
177
|
-
if args.any? && !args.first.kind_of?(Symbol)
|
178
|
-
raise ArgumentError, "First optional argument must be a Symbol, but was #{args.first.inspect}", caller
|
179
|
-
end
|
180
|
-
|
181
|
-
name = args.first
|
182
|
-
|
172
|
+
def self.repository(name = nil) # :yields: current_context
|
183
173
|
current_repository = if name
|
174
|
+
raise ArgumentError, "First optional argument must be a Symbol, but was #{args.first.inspect}" unless name.is_a?(Symbol)
|
184
175
|
Repository.context.detect { |r| r.name == name } || Repository.new(name)
|
185
176
|
else
|
186
177
|
Repository.context.last || Repository.new(Repository.default_name)
|
187
178
|
end
|
188
179
|
|
189
|
-
|
190
|
-
|
191
|
-
|
180
|
+
if block_given?
|
181
|
+
current_repository.scope { |*block_args| yield(*block_args) }
|
182
|
+
else
|
183
|
+
current_repository
|
184
|
+
end
|
192
185
|
end
|
193
186
|
|
194
187
|
# A logger should always be present. Lets be consistent with DO
|
data/lib/dm-core/adapters.rb
CHANGED
@@ -1,4 +1,22 @@
|
|
1
1
|
dir = Pathname(__FILE__).dirname.expand_path / 'adapters'
|
2
2
|
|
3
3
|
require dir / 'abstract_adapter'
|
4
|
+
require dir / 'in_memory_adapter'
|
5
|
+
|
6
|
+
# TODO Factor these out into dm-more
|
4
7
|
require dir / 'data_objects_adapter'
|
8
|
+
begin
|
9
|
+
require dir / 'sqlite3_adapter'
|
10
|
+
rescue LoadError
|
11
|
+
# ignore it
|
12
|
+
end
|
13
|
+
begin
|
14
|
+
require dir / 'mysql_adapter'
|
15
|
+
rescue LoadError
|
16
|
+
# ignore it
|
17
|
+
end
|
18
|
+
begin
|
19
|
+
require dir / 'postgres_adapter'
|
20
|
+
rescue LoadError
|
21
|
+
# ignore it
|
22
|
+
end
|
@@ -38,7 +38,7 @@ module DataMapper
|
|
38
38
|
# connection string for configuration.
|
39
39
|
def initialize(name, uri_or_options)
|
40
40
|
assert_kind_of 'name', name, Symbol
|
41
|
-
assert_kind_of 'uri_or_options', uri_or_options, Addressable::URI, Hash, String
|
41
|
+
assert_kind_of 'uri_or_options', uri_or_options, Addressable::URI, DataObjects::URI, Hash, String
|
42
42
|
|
43
43
|
@name = name
|
44
44
|
@uri = normalize_uri(uri_or_options)
|
@@ -46,12 +46,7 @@ module DataMapper
|
|
46
46
|
@resource_naming_convention = NamingConventions::Resource::UnderscoredAndPluralized
|
47
47
|
@field_naming_convention = NamingConventions::Field::Underscored
|
48
48
|
|
49
|
-
@transactions =
|
50
|
-
hash.delete_if do |k, v|
|
51
|
-
!k.respond_to?(:alive?) || !k.alive?
|
52
|
-
end
|
53
|
-
hash[key] = []
|
54
|
-
end
|
49
|
+
@transactions = {}
|
55
50
|
end
|
56
51
|
|
57
52
|
# TODO: move to dm-more/dm-migrations
|
@@ -144,7 +139,7 @@ module DataMapper
|
|
144
139
|
#
|
145
140
|
# TODO: move to dm-more/dm-transaction
|
146
141
|
def push_transaction(transaction)
|
147
|
-
|
142
|
+
transactions(Thread.current) << transaction
|
148
143
|
end
|
149
144
|
|
150
145
|
#
|
@@ -156,7 +151,7 @@ module DataMapper
|
|
156
151
|
#
|
157
152
|
# TODO: move to dm-more/dm-transaction
|
158
153
|
def pop_transaction
|
159
|
-
|
154
|
+
transactions(Thread.current).pop
|
160
155
|
end
|
161
156
|
|
162
157
|
#
|
@@ -169,7 +164,7 @@ module DataMapper
|
|
169
164
|
#
|
170
165
|
# TODO: move to dm-more/dm-transaction
|
171
166
|
def current_transaction
|
172
|
-
|
167
|
+
transactions(Thread.current).last
|
173
168
|
end
|
174
169
|
|
175
170
|
#
|
@@ -194,6 +189,18 @@ module DataMapper
|
|
194
189
|
def transaction_primitive
|
195
190
|
raise NotImplementedError
|
196
191
|
end
|
192
|
+
|
193
|
+
private
|
194
|
+
def transactions(thread)
|
195
|
+
unless @transactions[thread]
|
196
|
+
@transactions.delete_if do |key, value|
|
197
|
+
!key.respond_to?(:alive?) || !key.alive?
|
198
|
+
end
|
199
|
+
@transactions[thread] = []
|
200
|
+
end
|
201
|
+
@transactions[thread]
|
202
|
+
end
|
203
|
+
|
197
204
|
end
|
198
205
|
|
199
206
|
include Transaction
|
@@ -1,4 +1,4 @@
|
|
1
|
-
gem 'data_objects', '
|
1
|
+
gem 'data_objects', '~>0.9.9'
|
2
2
|
require 'data_objects'
|
3
3
|
|
4
4
|
module DataMapper
|
@@ -117,24 +117,26 @@ module DataMapper
|
|
117
117
|
protected
|
118
118
|
|
119
119
|
def normalize_uri(uri_or_options)
|
120
|
-
if uri_or_options.kind_of?(String)
|
121
|
-
uri_or_options =
|
120
|
+
if uri_or_options.kind_of?(String) || uri_or_options.kind_of?(Addressable::URI)
|
121
|
+
uri_or_options = DataObjects::URI.parse(uri_or_options)
|
122
122
|
end
|
123
123
|
|
124
|
-
if uri_or_options.kind_of?(
|
125
|
-
return uri_or_options
|
124
|
+
if uri_or_options.kind_of?(DataObjects::URI)
|
125
|
+
return uri_or_options
|
126
126
|
end
|
127
127
|
|
128
|
-
|
129
|
-
|
130
|
-
password = uri_or_options.delete(:password)
|
131
|
-
host = uri_or_options.delete(:host)
|
132
|
-
port = uri_or_options.delete(:port)
|
133
|
-
database = uri_or_options.delete(:database)
|
134
|
-
query = uri_or_options.to_a.map { |pair| pair * '=' } * '&'
|
135
|
-
query = nil if query == ''
|
128
|
+
query = uri_or_options.except(:adapter, :username, :password, :host, :port, :database).map { |pair| pair.join('=') }.join('&')
|
129
|
+
query = nil if query.blank?
|
136
130
|
|
137
|
-
return Addressable::URI.new(
|
131
|
+
return DataObjects::URI.parse(Addressable::URI.new(
|
132
|
+
:scheme => uri_or_options[:adapter].to_s,
|
133
|
+
:user => uri_or_options[:username],
|
134
|
+
:password => uri_or_options[:password],
|
135
|
+
:host => uri_or_options[:host],
|
136
|
+
:port => uri_or_options[:port],
|
137
|
+
:path => uri_or_options[:database],
|
138
|
+
:query => query
|
139
|
+
))
|
138
140
|
end
|
139
141
|
|
140
142
|
# TODO: clean up once transaction related methods move to dm-more/dm-transactions
|
@@ -164,7 +166,7 @@ module DataMapper
|
|
164
166
|
end
|
165
167
|
end
|
166
168
|
|
167
|
-
def with_connection
|
169
|
+
def with_connection
|
168
170
|
connection = nil
|
169
171
|
begin
|
170
172
|
connection = create_connection
|
@@ -177,7 +179,7 @@ module DataMapper
|
|
177
179
|
end
|
178
180
|
end
|
179
181
|
|
180
|
-
def with_reader(statement, bind_values = []
|
182
|
+
def with_reader(statement, bind_values = [])
|
181
183
|
with_connection do |connection|
|
182
184
|
reader = nil
|
183
185
|
begin
|
@@ -1,4 +1,4 @@
|
|
1
|
-
gem 'do_postgres', '
|
1
|
+
gem 'do_postgres', '~>0.9.9'
|
2
2
|
require 'do_postgres'
|
3
3
|
|
4
4
|
module DataMapper
|
@@ -86,7 +86,7 @@ module DataMapper
|
|
86
86
|
end
|
87
87
|
|
88
88
|
# TODO: move to dm-more/dm-migrations
|
89
|
-
def without_notices
|
89
|
+
def without_notices
|
90
90
|
# execute the block with NOTICE messages disabled
|
91
91
|
begin
|
92
92
|
execute('SET client_min_messages = warning')
|
data/lib/dm-core/associations.rb
CHANGED
@@ -45,8 +45,8 @@ module DataMapper
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def relationships(repository_name = default_repository_name)
|
48
|
-
@relationships ||=
|
49
|
-
@relationships[repository_name]
|
48
|
+
@relationships ||= {}
|
49
|
+
@relationships[repository_name] ||= repository_name == Repository.default_name ? {} : relationships(Repository.default_name).dup
|
50
50
|
end
|
51
51
|
|
52
52
|
def n
|
@@ -145,6 +145,7 @@ module DataMapper
|
|
145
145
|
#
|
146
146
|
# @api public
|
147
147
|
def belongs_to(name, options={})
|
148
|
+
@_valid_relations = false
|
148
149
|
relationship = ManyToOne.setup(name, self, options)
|
149
150
|
# Please leave this in - I will release contextual serialization soon
|
150
151
|
# which requires this -- guyvdb
|
@@ -48,7 +48,7 @@ module DataMapper
|
|
48
48
|
opts[:mutable] = true
|
49
49
|
|
50
50
|
names = [ opts[:child_model], opts[:parent_model].name ].sort
|
51
|
-
model_name = names.join
|
51
|
+
model_name = names.join.gsub("::", "")
|
52
52
|
storage_name = Extlib::Inflection.tableize(Extlib::Inflection.pluralize(names[0]) + names[1])
|
53
53
|
|
54
54
|
opts[:near_relationship_name] = Extlib::Inflection.tableize(model_name).to_sym
|
@@ -67,7 +67,7 @@ module DataMapper
|
|
67
67
|
EOS
|
68
68
|
|
69
69
|
names.each do |n|
|
70
|
-
model.belongs_to(Extlib::Inflection.underscore(n).to_sym)
|
70
|
+
model.belongs_to(Extlib::Inflection.underscore(n).gsub("/", "_").to_sym, :class_name => n)
|
71
71
|
end
|
72
72
|
|
73
73
|
Object.const_set(model_name, model)
|
@@ -48,7 +48,7 @@ module DataMapper
|
|
48
48
|
class Proxy
|
49
49
|
include Assertions
|
50
50
|
|
51
|
-
instance_methods.each { |m| undef_method m unless %w[ __id__ __send__
|
51
|
+
instance_methods.each { |m| undef_method m unless %w[ __id__ __send__ kind_of? respond_to? assert_kind_of should should_not instance_variable_set instance_variable_get ].include?(m.to_s) }
|
52
52
|
|
53
53
|
def replace(parent)
|
54
54
|
@parent = parent
|
@@ -72,7 +72,7 @@ module DataMapper
|
|
72
72
|
class Proxy
|
73
73
|
include Assertions
|
74
74
|
|
75
|
-
instance_methods.each { |m| undef_method m unless %w[ __id__ __send__ class kind_of? respond_to? assert_kind_of should should_not instance_variable_set instance_variable_get ].include?(m) }
|
75
|
+
instance_methods.each { |m| undef_method m unless %w[ __id__ __send__ class kind_of? respond_to? assert_kind_of should should_not instance_variable_set instance_variable_get ].include?(m.to_s) }
|
76
76
|
|
77
77
|
# FIXME: remove when RelationshipChain#get_children can return a Collection
|
78
78
|
def all(query = {})
|
@@ -132,7 +132,7 @@ module DataMapper
|
|
132
132
|
orphan_resource(super)
|
133
133
|
end
|
134
134
|
|
135
|
-
def delete(resource
|
135
|
+
def delete(resource)
|
136
136
|
assert_mutable
|
137
137
|
orphan_resource(super)
|
138
138
|
end
|
@@ -156,6 +156,15 @@ module DataMapper
|
|
156
156
|
resource
|
157
157
|
end
|
158
158
|
|
159
|
+
def new(attributes = {})
|
160
|
+
assert_mutable
|
161
|
+
raise UnsavedParentError, 'You cannot intialize until the parent is saved' if @parent.new_record?
|
162
|
+
attributes = default_attributes.merge(attributes)
|
163
|
+
resource = children.respond_to?(:new) ? super(attributes) : @relationship.child_model.new(attributes)
|
164
|
+
self << resource
|
165
|
+
resource
|
166
|
+
end
|
167
|
+
|
159
168
|
def create(attributes = {})
|
160
169
|
assert_mutable
|
161
170
|
raise UnsavedParentError, 'You cannot create until the parent is saved' if @parent.new_record?
|
@@ -297,11 +306,8 @@ module DataMapper
|
|
297
306
|
end
|
298
307
|
|
299
308
|
def method_missing(method, *args, &block)
|
300
|
-
results = children.
|
301
|
-
|
302
|
-
return self if LazyArray::RETURN_SELF.include?(method) && results.kind_of?(Array)
|
303
|
-
|
304
|
-
results
|
309
|
+
results = children.send(method, *args, &block)
|
310
|
+
results.equal?(children) ? self : results
|
305
311
|
end
|
306
312
|
end # class Proxy
|
307
313
|
end # module OneToMany
|