mongo_mapper-unstable 2010.2.3 → 2010.2.4

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2010.02.03
1
+ 2010.02.04
data/lib/mongo_mapper.rb CHANGED
@@ -102,25 +102,7 @@ end
102
102
 
103
103
  require 'mongo_mapper/support'
104
104
  require 'mongo_mapper/finder_options'
105
- require 'mongo_mapper/dynamic_finder'
106
- require 'mongo_mapper/descendant_appends'
107
-
108
105
  require 'mongo_mapper/plugins'
109
- require 'mongo_mapper/plugins/associations'
110
- require 'mongo_mapper/plugins/callbacks'
111
- require 'mongo_mapper/plugins/clone'
112
- require 'mongo_mapper/plugins/descendants'
113
- require 'mongo_mapper/plugins/dirty'
114
- require 'mongo_mapper/plugins/equality'
115
- require 'mongo_mapper/plugins/identity_map'
116
- require 'mongo_mapper/plugins/inspect'
117
- require 'mongo_mapper/plugins/keys'
118
- require 'mongo_mapper/plugins/logger'
119
- require 'mongo_mapper/plugins/pagination'
120
- require 'mongo_mapper/plugins/protected'
121
- require 'mongo_mapper/plugins/rails'
122
- require 'mongo_mapper/plugins/serialization'
123
- require 'mongo_mapper/plugins/validations'
124
106
 
125
107
  require 'mongo_mapper/document'
126
108
  require 'mongo_mapper/embedded_document'
@@ -1,13 +1,13 @@
1
1
  module MongoMapper
2
2
  module Document
3
- extend DescendantAppends
3
+ extend Support::DescendantAppends
4
4
 
5
5
  def self.included(model)
6
6
  model.class_eval do
7
7
  include InstanceMethods
8
+ extend Support::Find
8
9
  extend ClassMethods
9
- extend Finders
10
- extend Plugins
10
+ extend Plugins
11
11
 
12
12
  plugin Plugins::Associations
13
13
  plugin Plugins::Clone
@@ -26,10 +26,10 @@ module MongoMapper
26
26
 
27
27
  extend Plugins::Validations::DocumentMacros
28
28
  end
29
-
29
+
30
30
  super
31
31
  end
32
-
32
+
33
33
  module ClassMethods
34
34
  def inherited(subclass)
35
35
  subclass.set_collection_name(collection_name)
@@ -47,7 +47,7 @@ module MongoMapper
47
47
  end
48
48
 
49
49
  def find(*args)
50
- find_all_first_last_error(args)
50
+ assert_no_first_last_or_all(args)
51
51
  options = args.extract_options!
52
52
  return nil if args.size == 0
53
53
 
@@ -59,7 +59,7 @@ module MongoMapper
59
59
  end
60
60
 
61
61
  def find!(*args)
62
- find_all_first_last_error(args)
62
+ assert_no_first_last_or_all(args)
63
63
  options = args.extract_options!
64
64
  raise DocumentNotFound, "Couldn't find without an ID" if args.size == 0
65
65
 
@@ -70,10 +70,6 @@ module MongoMapper
70
70
  end
71
71
  end
72
72
 
73
- def find_or_create(arg)
74
- first(arg) || create(arg)
75
- end
76
-
77
73
  def find_each(options={})
78
74
  criteria, options = to_finder_options(options)
79
75
  collection.find(criteria, options).each do |doc|
@@ -85,6 +81,14 @@ module MongoMapper
85
81
  find(id)
86
82
  end
87
83
 
84
+ def first_or_create(arg)
85
+ first(arg) || create(arg)
86
+ end
87
+
88
+ def first_or_new(arg)
89
+ first(arg) || new(arg)
90
+ end
91
+
88
92
  def first(options={})
89
93
  find_one(options)
90
94
  end
@@ -136,46 +140,46 @@ module MongoMapper
136
140
  end
137
141
 
138
142
  def destroy_all(options={})
139
- all(options).each(&:destroy)
143
+ find_each(options) { |document| document.destroy }
140
144
  end
141
-
145
+
142
146
  def increment(*args)
143
147
  modifier_update('$inc', args)
144
148
  end
145
-
149
+
146
150
  def decrement(*args)
147
151
  criteria, keys = criteria_and_keys_from_args(args)
148
152
  values, to_decrement = keys.values, {}
149
153
  keys.keys.each_with_index { |k, i| to_decrement[k] = -values[i].abs }
150
154
  collection.update(criteria, {'$inc' => to_decrement}, :multi => true)
151
155
  end
152
-
156
+
153
157
  def set(*args)
154
158
  modifier_update('$set', args)
155
159
  end
156
-
160
+
157
161
  def push(*args)
158
162
  modifier_update('$push', args)
159
163
  end
160
-
164
+
161
165
  def push_all(*args)
162
166
  modifier_update('$pushAll', args)
163
167
  end
164
-
168
+
165
169
  def push_uniq(*args)
166
170
  criteria, keys = criteria_and_keys_from_args(args)
167
171
  keys.each { |key, value | criteria[key] = {'$ne' => value} }
168
172
  collection.update(criteria, {'$push' => keys}, :multi => true)
169
173
  end
170
-
174
+
171
175
  def pull(*args)
172
176
  modifier_update('$pull', args)
173
177
  end
174
-
178
+
175
179
  def pull_all(*args)
176
180
  modifier_update('$pullAll', args)
177
181
  end
178
-
182
+
179
183
  def pop(*args)
180
184
  modifier_update('$pop', args)
181
185
  end
@@ -266,7 +270,7 @@ module MongoMapper
266
270
  [to_criteria(criteria), keys]
267
271
  end
268
272
 
269
- def find_all_first_last_error(args)
273
+ def assert_no_first_last_or_all(args)
270
274
  if args[0] == :first || args[0] == :last || args[0] == :all
271
275
  raise ArgumentError, "#{self}.find(:#{args}) is no longer supported, use #{self}.#{args} instead."
272
276
  end
@@ -276,11 +280,11 @@ module MongoMapper
276
280
  ids = ids.flatten.compact.uniq
277
281
  find_many(options.merge(:_id => ids)).compact
278
282
  end
279
-
283
+
280
284
  def find_some!(ids, options={})
281
285
  ids = ids.flatten.compact.uniq
282
286
  documents = find_some(ids, options)
283
-
287
+
284
288
  if ids.size == documents.size
285
289
  documents
286
290
  else
@@ -364,21 +368,11 @@ module MongoMapper
364
368
  options.assert_valid_keys(:safe)
365
369
  save(options) || raise(DocumentNotValid.new(self))
366
370
  end
367
-
368
- def update_attributes(attrs={})
369
- self.attributes = attrs
370
- save
371
- end
372
-
373
- def update_attributes!(attrs={})
374
- self.attributes = attrs
375
- save!
376
- end
377
371
 
378
372
  def destroy
379
373
  delete
380
374
  end
381
-
375
+
382
376
  def delete
383
377
  self.class.delete(id) unless new?
384
378
  end
@@ -408,7 +402,7 @@ module MongoMapper
408
402
  end
409
403
 
410
404
  def save_to_collection(options={})
411
- safe = options.delete(:safe) || false
405
+ safe = options[:safe] || false
412
406
  @new = false
413
407
  collection.save(to_mongo, :safe => safe)
414
408
  end
@@ -1,12 +1,12 @@
1
1
  module MongoMapper
2
2
  module EmbeddedDocument
3
- extend DescendantAppends
3
+ extend Support::DescendantAppends
4
4
 
5
5
  def self.included(model)
6
6
  model.class_eval do
7
7
  include InstanceMethods
8
8
  extend ClassMethods
9
- extend Plugins
9
+ extend Plugins
10
10
 
11
11
  plugin Plugins::Associations
12
12
  plugin Plugins::Clone
@@ -32,9 +32,7 @@ module MongoMapper
32
32
  end
33
33
 
34
34
  def embedded_in(owner_name)
35
- define_method(owner_name) do
36
- self._parent_document
37
- end
35
+ define_method(owner_name) { _parent_document }
38
36
  end
39
37
  end
40
38
 
@@ -52,16 +50,6 @@ module MongoMapper
52
50
  end
53
51
  result
54
52
  end
55
-
56
- def update_attributes(attrs={})
57
- self.attributes = attrs
58
- self.save
59
- end
60
-
61
- def update_attributes!(attrs={})
62
- self.attributes = attrs
63
- self.save!
64
- end
65
53
  end # InstanceMethods
66
54
  end # EmbeddedDocument
67
55
  end # MongoMapper
@@ -11,4 +11,20 @@ module MongoMapper
11
11
  plugins << mod
12
12
  end
13
13
  end
14
- end
14
+ end
15
+
16
+ require 'mongo_mapper/plugins/associations'
17
+ require 'mongo_mapper/plugins/callbacks'
18
+ require 'mongo_mapper/plugins/clone'
19
+ require 'mongo_mapper/plugins/descendants'
20
+ require 'mongo_mapper/plugins/dirty'
21
+ require 'mongo_mapper/plugins/equality'
22
+ require 'mongo_mapper/plugins/identity_map'
23
+ require 'mongo_mapper/plugins/inspect'
24
+ require 'mongo_mapper/plugins/keys'
25
+ require 'mongo_mapper/plugins/logger'
26
+ require 'mongo_mapper/plugins/pagination'
27
+ require 'mongo_mapper/plugins/protected'
28
+ require 'mongo_mapper/plugins/rails'
29
+ require 'mongo_mapper/plugins/serialization'
30
+ require 'mongo_mapper/plugins/validations'
@@ -4,7 +4,7 @@ module MongoMapper
4
4
  class EmbeddedCollection < Collection
5
5
  def build(attributes={})
6
6
  doc = klass.new(attributes)
7
- assign_root_document(doc)
7
+ assign_references(doc)
8
8
  self << doc
9
9
  doc
10
10
  end
@@ -22,7 +22,7 @@ module MongoMapper
22
22
  def <<(*docs)
23
23
  load_target
24
24
  docs.each do |doc|
25
- assign_root_document(doc)
25
+ assign_references(doc)
26
26
  target << doc
27
27
  end
28
28
  end
@@ -38,7 +38,7 @@ module MongoMapper
38
38
  end
39
39
  end
40
40
 
41
- def assign_root_document(*docs)
41
+ def assign_references(*docs)
42
42
  docs.each do |doc|
43
43
  doc._root_document = _root_document
44
44
  doc._parent_document = owner
@@ -2,7 +2,7 @@ module MongoMapper
2
2
  module Plugins
3
3
  module Associations
4
4
  class InArrayProxy < Collection
5
- include ::MongoMapper::Finders
5
+ include Support::Find
6
6
 
7
7
  def find(*args)
8
8
  options = args.extract_options!
@@ -2,7 +2,7 @@ module MongoMapper
2
2
  module Plugins
3
3
  module Associations
4
4
  class ManyDocumentsProxy < Collection
5
- include ::MongoMapper::Finders
5
+ include Support::Find
6
6
 
7
7
  def find(*args)
8
8
  options = args.extract_options!
@@ -13,7 +13,7 @@ module MongoMapper
13
13
  def find_target
14
14
  (@_values || []).map do |hash|
15
15
  child = polymorphic_class(hash).load(hash)
16
- assign_root_document(child)
16
+ assign_references(child)
17
17
  child
18
18
  end
19
19
  end
@@ -13,7 +13,7 @@ module MongoMapper
13
13
  def find_target
14
14
  (@_values || []).map do |v|
15
15
  child = klass.load(v)
16
- assign_root_document(child)
16
+ assign_references(child)
17
17
  child
18
18
  end
19
19
  end
@@ -4,7 +4,7 @@ module MongoMapper
4
4
  def self.configure(model)
5
5
  model.key :_id, ObjectId
6
6
  end
7
-
7
+
8
8
  module ClassMethods
9
9
  def inherited(descendant)
10
10
  descendant.instance_variable_set(:@keys, keys.dup)
@@ -143,25 +143,31 @@ module MongoMapper
143
143
  end
144
144
  end
145
145
  end
146
-
146
+
147
147
  module InstanceMethods
148
- def initialize(attrs={}, from_db=false)
148
+ def initialize(attrs={}, from_database=false)
149
149
  unless attrs.nil?
150
150
  provided_keys = attrs.keys.map { |k| k.to_s }
151
151
  unless provided_keys.include?('_id') || provided_keys.include?('id')
152
152
  write_key :_id, Mongo::ObjectID.new
153
153
  end
154
154
  end
155
-
156
- @new = from_db ? false : true
157
- self._type = self.class.name if respond_to?(:_type=)
158
- self.attributes = attrs
155
+
156
+ assign_type_if_present
157
+
158
+ if from_database
159
+ @new = false
160
+ self.attributes = attrs
161
+ else
162
+ @new = true
163
+ assign(attrs)
164
+ end
159
165
  end
160
-
166
+
161
167
  def new?
162
168
  @new
163
169
  end
164
-
170
+
165
171
  def attributes=(attrs)
166
172
  return if attrs.blank?
167
173
 
@@ -193,7 +199,21 @@ module MongoMapper
193
199
  attrs
194
200
  end
195
201
  alias :to_mongo :attributes
196
-
202
+
203
+ def assign(attrs={})
204
+ self.attributes = attrs
205
+ end
206
+
207
+ def update_attributes(attrs={})
208
+ assign(attrs)
209
+ save
210
+ end
211
+
212
+ def update_attributes!(attrs={})
213
+ assign(attrs)
214
+ save!
215
+ end
216
+
197
217
  def id
198
218
  _id
199
219
  end
@@ -236,6 +256,10 @@ module MongoMapper
236
256
  end
237
257
 
238
258
  private
259
+ def assign_type_if_present
260
+ self._type = self.class.name if respond_to?(:_type=)
261
+ end
262
+
239
263
  def ensure_key_exists(name)
240
264
  self.class.key(name) unless respond_to?("#{name}=")
241
265
  end
@@ -18,6 +18,10 @@ module MongoMapper
18
18
  end
19
19
 
20
20
  module InstanceMethods
21
+ def assign(attrs={})
22
+ super(filter_protected_attrs(attrs))
23
+ end
24
+
21
25
  def update_attributes(attrs={})
22
26
  super(filter_protected_attrs(attrs))
23
27
  end
@@ -211,4 +211,7 @@ class Mongo::ObjectID
211
211
  def to_json(options = nil)
212
212
  %Q("#{to_s}")
213
213
  end
214
- end
214
+ end
215
+
216
+ require 'mongo_mapper/support/descendant_appends'
217
+ require 'mongo_mapper/support/find'
@@ -0,0 +1,46 @@
1
+ module MongoMapper
2
+ module Support
3
+ module DescendantAppends
4
+ def included(model)
5
+ extra_extensions.each { |extension| model.extend(extension) }
6
+ extra_inclusions.each { |inclusion| model.send(:include, inclusion) }
7
+ descendants << model
8
+ end
9
+
10
+ # @api public
11
+ def descendants
12
+ @descendants ||= Set.new
13
+ end
14
+
15
+ # @api public
16
+ def append_extensions(*extensions)
17
+ extra_extensions.concat extensions
18
+
19
+ # Add the extension to existing descendants
20
+ descendants.each do |model|
21
+ extensions.each { |extension| model.extend(extension) }
22
+ end
23
+ end
24
+
25
+ # @api public
26
+ def append_inclusions(*inclusions)
27
+ extra_inclusions.concat inclusions
28
+
29
+ # Add the inclusion to existing descendants
30
+ descendants.each do |model|
31
+ inclusions.each { |inclusion| model.send(:include, inclusion) }
32
+ end
33
+ end
34
+
35
+ # @api private
36
+ def extra_extensions
37
+ @extra_extensions ||= []
38
+ end
39
+
40
+ # @api private
41
+ def extra_inclusions
42
+ @extra_inclusions ||= []
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,77 @@
1
+ module MongoMapper
2
+ module Support
3
+ # @api private
4
+ module Find
5
+ def dynamic_find(finder, args)
6
+ attributes = {}
7
+
8
+ finder.attributes.each_with_index do |attr, index|
9
+ attributes[attr] = args[index]
10
+ end
11
+
12
+ options = args.extract_options!.merge(attributes)
13
+
14
+ if result = send(finder.finder, options)
15
+ result
16
+ else
17
+ if finder.raise?
18
+ raise DocumentNotFound, "Couldn't find Document with #{attributes.inspect} in collection named #{collection.name}"
19
+ end
20
+
21
+ if finder.instantiator
22
+ self.send(finder.instantiator, attributes)
23
+ end
24
+ end
25
+ end
26
+
27
+ class DynamicFinder
28
+ attr_reader :method, :attributes, :finder, :bang, :instantiator
29
+
30
+ def initialize(method)
31
+ @method = method
32
+ @finder = :first
33
+ @bang = false
34
+ match
35
+ end
36
+
37
+ def found?
38
+ @finder.present?
39
+ end
40
+
41
+ def raise?
42
+ bang == true
43
+ end
44
+
45
+ protected
46
+ def match
47
+ case method.to_s
48
+ when /^find_(all_by|by)_([_a-zA-Z]\w*)$/
49
+ @finder = :all if $1 == 'all_by'
50
+ names = $2
51
+ when /^find_by_([_a-zA-Z]\w*)\!$/
52
+ @bang = true
53
+ names = $1
54
+ when /^find_or_(initialize|create)_by_([_a-zA-Z]\w*)$/
55
+ @instantiator = $1 == 'initialize' ? :new : :create
56
+ names = $2
57
+ else
58
+ @finder = nil
59
+ end
60
+
61
+ @attributes = names && names.split('_and_')
62
+ end
63
+ end
64
+
65
+ protected
66
+ def method_missing(method, *args, &block)
67
+ finder = DynamicFinder.new(method)
68
+
69
+ if finder.found?
70
+ dynamic_find(finder, args)
71
+ else
72
+ super
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -407,24 +407,43 @@ class DocumentTest < Test::Unit::TestCase
407
407
  end
408
408
  end
409
409
 
410
- context "find_or_create" do
410
+ context "first_or_create" do
411
411
  should "find if exists" do
412
412
  created = @document.create(:first_name => 'John', :last_name => 'Nunemaker')
413
413
  lambda {
414
- found = @document.find_or_create(:first_name => 'John', :last_name => 'Nunemaker')
414
+ found = @document.first_or_create(:first_name => 'John', :last_name => 'Nunemaker')
415
415
  found.should == created
416
416
  }.should_not change { @document.count }
417
417
  end
418
418
 
419
419
  should "create if not found" do
420
420
  lambda {
421
- created = @document.find_or_create(:first_name => 'John', :last_name => 'Nunemaker')
421
+ created = @document.first_or_create(:first_name => 'John', :last_name => 'Nunemaker')
422
422
  created.first_name.should == 'John'
423
423
  created.last_name.should == 'Nunemaker'
424
424
  }.should change { @document.count }.by(1)
425
425
  end
426
426
  end
427
427
 
428
+ context "first_or_new" do
429
+ should "find if exists" do
430
+ created = @document.create(:first_name => 'John', :last_name => 'Nunemaker')
431
+ lambda {
432
+ found = @document.first_or_new(:first_name => 'John', :last_name => 'Nunemaker')
433
+ found.should == created
434
+ }.should_not change { @document.count }
435
+ end
436
+
437
+ should "initialize if not found" do
438
+ lambda {
439
+ created = @document.first_or_new(:first_name => 'John', :last_name => 'Nunemaker')
440
+ created.first_name.should == 'John'
441
+ created.last_name.should == 'Nunemaker'
442
+ created.should be_new
443
+ }.should_not change { @document.count }
444
+ end
445
+ end
446
+
428
447
  context "ClassMethods#delete (single document)" do
429
448
  setup do
430
449
  @doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
@@ -36,6 +36,22 @@ class ProtectedTest < Test::Unit::TestCase
36
36
  @doc.admin.should be_true
37
37
  end
38
38
 
39
+ should "ignore protected attribute on #initialize" do
40
+ doc = @doc_class.new(:name => 'John', :admin => true)
41
+ doc.admin.should be_false
42
+ doc.name.should == 'John'
43
+ end
44
+
45
+ should "not ignore protected attributes on #initialize from the database" do
46
+ doc = @doc_class.new(:name => 'John')
47
+ doc.admin = true
48
+ doc.save!
49
+
50
+ doc = @doc_class.first(:name => 'John')
51
+ doc.admin.should be_true
52
+ doc.name.should == 'John'
53
+ end
54
+
39
55
  should 'ignore protected attribute on #update_attributes' do
40
56
  @doc.update_attributes(:name => 'Ren Hoek', :admin => true)
41
57
  @doc.name.should == 'Ren Hoek'
@@ -1,125 +1,123 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class DynamicFinderTest < Test::Unit::TestCase
4
- include MongoMapper
5
-
6
4
  should "initialize with method" do
7
- finder = DynamicFinder.new(:foobar)
5
+ finder = MongoMapper::Support::Find::DynamicFinder.new(:foobar)
8
6
  finder.method.should == :foobar
9
7
  end
10
8
 
11
9
  context "found?" do
12
10
  should "be true for find_by" do
13
- DynamicFinder.new(:find_by_foo).found?.should be_true
11
+ MongoMapper::Support::Find::DynamicFinder.new(:find_by_foo).found?.should be_true
14
12
  end
15
13
 
16
14
  should "be true for find_by with !" do
17
- DynamicFinder.new(:find_by_foo!).found?.should be_true
15
+ MongoMapper::Support::Find::DynamicFinder.new(:find_by_foo!).found?.should be_true
18
16
  end
19
17
 
20
18
  should "be true for find_all_by" do
21
- DynamicFinder.new(:find_all_by_foo).found?.should be_true
19
+ MongoMapper::Support::Find::DynamicFinder.new(:find_all_by_foo).found?.should be_true
22
20
  end
23
21
 
24
22
  should "be true for find_or_initialize_by" do
25
- DynamicFinder.new(:find_or_initialize_by_foo).found?.should be_true
23
+ MongoMapper::Support::Find::DynamicFinder.new(:find_or_initialize_by_foo).found?.should be_true
26
24
  end
27
25
 
28
26
  should "be true for find_or_create_by" do
29
- DynamicFinder.new(:find_or_create_by_foo).found?.should be_true
27
+ MongoMapper::Support::Find::DynamicFinder.new(:find_or_create_by_foo).found?.should be_true
30
28
  end
31
29
 
32
30
  should "be false for anything else" do
33
31
  [:foobar, :bazwick].each do |method|
34
- DynamicFinder.new(method).found?.should be_false
32
+ MongoMapper::Support::Find::DynamicFinder.new(method).found?.should be_false
35
33
  end
36
34
  end
37
35
  end
38
36
 
39
37
  context "find_all_by" do
40
38
  should "parse one attribute" do
41
- DynamicFinder.new(:find_all_by_foo).attributes.should == %w(foo)
39
+ MongoMapper::Support::Find::DynamicFinder.new(:find_all_by_foo).attributes.should == %w(foo)
42
40
  end
43
41
 
44
42
  should "parse multiple attributes" do
45
- DynamicFinder.new(:find_all_by_foo_and_bar).attributes.should == %w(foo bar)
46
- DynamicFinder.new(:find_all_by_foo_and_bar_and_baz).attributes.should == %w(foo bar baz)
43
+ MongoMapper::Support::Find::DynamicFinder.new(:find_all_by_foo_and_bar).attributes.should == %w(foo bar)
44
+ MongoMapper::Support::Find::DynamicFinder.new(:find_all_by_foo_and_bar_and_baz).attributes.should == %w(foo bar baz)
47
45
  end
48
46
 
49
47
  should "set finder to :all" do
50
- DynamicFinder.new(:find_all_by_foo_and_bar).finder.should == :all
48
+ MongoMapper::Support::Find::DynamicFinder.new(:find_all_by_foo_and_bar).finder.should == :all
51
49
  end
52
50
  end
53
51
 
54
52
  context "find_by" do
55
53
  should "parse one attribute" do
56
- DynamicFinder.new(:find_by_foo).attributes.should == %w(foo)
54
+ MongoMapper::Support::Find::DynamicFinder.new(:find_by_foo).attributes.should == %w(foo)
57
55
  end
58
56
 
59
57
  should "parse multiple attributes" do
60
- DynamicFinder.new(:find_by_foo_and_bar).attributes.should == %w(foo bar)
58
+ MongoMapper::Support::Find::DynamicFinder.new(:find_by_foo_and_bar).attributes.should == %w(foo bar)
61
59
  end
62
60
 
63
61
  should "set finder to :first" do
64
- DynamicFinder.new(:find_by_foo).finder.should == :first
62
+ MongoMapper::Support::Find::DynamicFinder.new(:find_by_foo).finder.should == :first
65
63
  end
66
64
 
67
65
  should "set bang to false" do
68
- DynamicFinder.new(:find_by_foo).bang.should be_false
66
+ MongoMapper::Support::Find::DynamicFinder.new(:find_by_foo).bang.should be_false
69
67
  end
70
68
  end
71
69
 
72
70
  context "find_by with !" do
73
71
  should "parse one attribute" do
74
- DynamicFinder.new(:find_by_foo!).attributes.should == %w(foo)
72
+ MongoMapper::Support::Find::DynamicFinder.new(:find_by_foo!).attributes.should == %w(foo)
75
73
  end
76
74
 
77
75
  should "parse multiple attributes" do
78
- DynamicFinder.new(:find_by_foo_and_bar!).attributes.should == %w(foo bar)
76
+ MongoMapper::Support::Find::DynamicFinder.new(:find_by_foo_and_bar!).attributes.should == %w(foo bar)
79
77
  end
80
78
 
81
79
  should "set finder to :first" do
82
- DynamicFinder.new(:find_by_foo!).finder.should == :first
80
+ MongoMapper::Support::Find::DynamicFinder.new(:find_by_foo!).finder.should == :first
83
81
  end
84
82
 
85
83
  should "set bang to true" do
86
- DynamicFinder.new(:find_by_foo!).bang.should be_true
84
+ MongoMapper::Support::Find::DynamicFinder.new(:find_by_foo!).bang.should be_true
87
85
  end
88
86
  end
89
87
 
90
88
  context "find_or_initialize_by" do
91
89
  should "parse one attribute" do
92
- DynamicFinder.new(:find_or_initialize_by_foo).attributes.should == %w(foo)
90
+ MongoMapper::Support::Find::DynamicFinder.new(:find_or_initialize_by_foo).attributes.should == %w(foo)
93
91
  end
94
92
 
95
93
  should "parse multiple attributes" do
96
- DynamicFinder.new(:find_or_initialize_by_foo_and_bar).attributes.should == %w(foo bar)
94
+ MongoMapper::Support::Find::DynamicFinder.new(:find_or_initialize_by_foo_and_bar).attributes.should == %w(foo bar)
97
95
  end
98
96
 
99
97
  should "set finder to :first" do
100
- DynamicFinder.new(:find_or_initialize_by_foo).finder.should == :first
98
+ MongoMapper::Support::Find::DynamicFinder.new(:find_or_initialize_by_foo).finder.should == :first
101
99
  end
102
100
 
103
101
  should "set instantiator to new" do
104
- DynamicFinder.new(:find_or_initialize_by_foo).instantiator.should == :new
102
+ MongoMapper::Support::Find::DynamicFinder.new(:find_or_initialize_by_foo).instantiator.should == :new
105
103
  end
106
104
  end
107
105
 
108
106
  context "find_or_create_by" do
109
107
  should "parse one attribute" do
110
- DynamicFinder.new(:find_or_create_by_foo).attributes.should == %w(foo)
108
+ MongoMapper::Support::Find::DynamicFinder.new(:find_or_create_by_foo).attributes.should == %w(foo)
111
109
  end
112
110
 
113
111
  should "parse multiple attributes" do
114
- DynamicFinder.new(:find_or_create_by_foo_and_bar).attributes.should == %w(foo bar)
112
+ MongoMapper::Support::Find::DynamicFinder.new(:find_or_create_by_foo_and_bar).attributes.should == %w(foo bar)
115
113
  end
116
114
 
117
115
  should "set finder to :first" do
118
- DynamicFinder.new(:find_or_create_by_foo).finder.should == :first
116
+ MongoMapper::Support::Find::DynamicFinder.new(:find_or_create_by_foo).finder.should == :first
119
117
  end
120
118
 
121
119
  should "set instantiator to new" do
122
- DynamicFinder.new(:find_or_create_by_foo).instantiator.should == :create
120
+ MongoMapper::Support::Find::DynamicFinder.new(:find_or_create_by_foo).instantiator.should == :create
123
121
  end
124
122
  end
125
123
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongo_mapper-unstable
3
3
  version: !ruby/object:Gem::Version
4
- version: 2010.2.3
4
+ version: 2010.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Nunemaker
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-02-03 00:00:00 -05:00
12
+ date: 2010-02-04 00:00:00 -05:00
13
13
  default_executable: mmconsole
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -99,9 +99,7 @@ files:
99
99
  - VERSION
100
100
  - bin/mmconsole
101
101
  - lib/mongo_mapper.rb
102
- - lib/mongo_mapper/descendant_appends.rb
103
102
  - lib/mongo_mapper/document.rb
104
- - lib/mongo_mapper/dynamic_finder.rb
105
103
  - lib/mongo_mapper/embedded_document.rb
106
104
  - lib/mongo_mapper/finder_options.rb
107
105
  - lib/mongo_mapper/plugins.rb
@@ -134,6 +132,8 @@ files:
134
132
  - lib/mongo_mapper/plugins/serialization.rb
135
133
  - lib/mongo_mapper/plugins/validations.rb
136
134
  - lib/mongo_mapper/support.rb
135
+ - lib/mongo_mapper/support/descendant_appends.rb
136
+ - lib/mongo_mapper/support/find.rb
137
137
  - mongo_mapper.gemspec
138
138
  - performance/read_write.rb
139
139
  - specs.watchr
@@ -1,44 +0,0 @@
1
- module MongoMapper
2
- module DescendantAppends
3
- def included(model)
4
- extra_extensions.each { |extension| model.extend(extension) }
5
- extra_inclusions.each { |inclusion| model.send(:include, inclusion) }
6
- descendants << model
7
- end
8
-
9
- # @api public
10
- def descendants
11
- @descendants ||= Set.new
12
- end
13
-
14
- # @api public
15
- def append_extensions(*extensions)
16
- extra_extensions.concat extensions
17
-
18
- # Add the extension to existing descendants
19
- descendants.each do |model|
20
- extensions.each { |extension| model.extend(extension) }
21
- end
22
- end
23
-
24
- # @api public
25
- def append_inclusions(*inclusions)
26
- extra_inclusions.concat inclusions
27
-
28
- # Add the inclusion to existing descendants
29
- descendants.each do |model|
30
- inclusions.each { |inclusion| model.send(:include, inclusion) }
31
- end
32
- end
33
-
34
- # @api private
35
- def extra_extensions
36
- @extra_extensions ||= []
37
- end
38
-
39
- # @api private
40
- def extra_inclusions
41
- @extra_inclusions ||= []
42
- end
43
- end
44
- end
@@ -1,74 +0,0 @@
1
- module MongoMapper
2
- # @api private
3
- module Finders
4
- def dynamic_find(finder, args)
5
- attributes = {}
6
- finder.attributes.each_with_index do |attr, index|
7
- attributes[attr] = args[index]
8
- end
9
-
10
- options = args.extract_options!.merge(attributes)
11
-
12
- if result = send(finder.finder, options)
13
- result
14
- else
15
- if finder.raise?
16
- raise DocumentNotFound, "Couldn't find Document with #{attributes.inspect} in collection named #{collection.name}"
17
- end
18
-
19
- if finder.instantiator
20
- self.send(finder.instantiator, attributes)
21
- end
22
- end
23
- end
24
-
25
- protected
26
- def method_missing(method, *args, &block)
27
- finder = DynamicFinder.new(method)
28
-
29
- if finder.found?
30
- dynamic_find(finder, args)
31
- else
32
- super
33
- end
34
- end
35
- end
36
-
37
- class DynamicFinder
38
- attr_reader :method, :attributes, :finder, :bang, :instantiator
39
-
40
- def initialize(method)
41
- @method = method
42
- @finder = :first
43
- @bang = false
44
- match
45
- end
46
-
47
- def found?
48
- @finder.present?
49
- end
50
-
51
- def raise?
52
- bang == true
53
- end
54
-
55
- protected
56
- def match
57
- case method.to_s
58
- when /^find_(all_by|by)_([_a-zA-Z]\w*)$/
59
- @finder = :all if $1 == 'all_by'
60
- names = $2
61
- when /^find_by_([_a-zA-Z]\w*)\!$/
62
- @bang = true
63
- names = $1
64
- when /^find_or_(initialize|create)_by_([_a-zA-Z]\w*)$/
65
- @instantiator = $1 == 'initialize' ? :new : :create
66
- names = $2
67
- else
68
- @finder = nil
69
- end
70
-
71
- @attributes = names && names.split('_and_')
72
- end
73
- end
74
- end