mongo_mapper-unstable 2010.2.9 → 2010.2.10
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/VERSION +1 -1
- data/lib/mongo_mapper/document.rb +6 -6
- data/lib/mongo_mapper/plugins/associations/base.rb +26 -24
- data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +5 -5
- data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +3 -3
- data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +1 -1
- data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +2 -2
- data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +2 -2
- data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +1 -1
- data/lib/mongo_mapper/plugins/associations/one_proxy.rb +2 -2
- data/lib/mongo_mapper/plugins/associations/proxy.rb +7 -7
- data/lib/mongo_mapper/plugins/associations.rb +16 -15
- data/lib/mongo_mapper/plugins/identity_map.rb +4 -4
- data/lib/mongo_mapper/plugins/pagination/proxy.rb +68 -0
- data/lib/mongo_mapper/plugins/pagination.rb +6 -67
- data/lib/mongo_mapper/plugins.rb +15 -14
- data/lib/mongo_mapper/query.rb +130 -0
- data/lib/mongo_mapper/support.rb +9 -11
- data/lib/mongo_mapper.rb +5 -5
- data/mongo_mapper.gemspec +55 -38
- data/test/unit/associations/test_base.rb +4 -4
- data/test/unit/test_pagination.rb +30 -30
- data/test/unit/{test_finder_options.rb → test_query.rb} +71 -66
- data/test/unit/test_support.rb +8 -0
- metadata +6 -5
- data/lib/mongo_mapper/finder_options.rb +0 -127
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2010.02.
|
1
|
+
2010.02.10
|
@@ -71,7 +71,7 @@ module MongoMapper
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def find_each(options={})
|
74
|
-
criteria, options =
|
74
|
+
criteria, options = to_query(options)
|
75
75
|
collection.find(criteria, options).each do |doc|
|
76
76
|
yield load(doc)
|
77
77
|
end
|
@@ -294,7 +294,7 @@ module MongoMapper
|
|
294
294
|
|
295
295
|
# All query methods that load documents pass through find_one or find_many
|
296
296
|
def find_one(options={})
|
297
|
-
criteria, options =
|
297
|
+
criteria, options = to_query(options)
|
298
298
|
if doc = collection.find_one(criteria, options)
|
299
299
|
load(doc)
|
300
300
|
end
|
@@ -302,7 +302,7 @@ module MongoMapper
|
|
302
302
|
|
303
303
|
# All query methods that load documents pass through find_one or find_many
|
304
304
|
def find_many(options)
|
305
|
-
criteria, options =
|
305
|
+
criteria, options = to_query(options)
|
306
306
|
collection.find(criteria, options).to_a.map do |doc|
|
307
307
|
load(doc)
|
308
308
|
end
|
@@ -341,11 +341,11 @@ module MongoMapper
|
|
341
341
|
end
|
342
342
|
|
343
343
|
def to_criteria(options={})
|
344
|
-
|
344
|
+
Query.new(self, options).criteria
|
345
345
|
end
|
346
346
|
|
347
|
-
def
|
348
|
-
|
347
|
+
def to_query(options={})
|
348
|
+
Query.new(self, options).to_a
|
349
349
|
end
|
350
350
|
end
|
351
351
|
|
@@ -2,28 +2,22 @@ module MongoMapper
|
|
2
2
|
module Plugins
|
3
3
|
module Associations
|
4
4
|
class Base
|
5
|
-
attr_reader :type, :name, :options, :
|
5
|
+
attr_reader :type, :name, :options, :query_options
|
6
6
|
|
7
7
|
# Options that should not be considered MongoDB query options/criteria
|
8
8
|
AssociationOptions = [:as, :class, :class_name, :dependent, :extend, :foreign_key, :in, :polymorphic]
|
9
9
|
|
10
10
|
def initialize(type, name, options={}, &extension)
|
11
|
-
@type, @name, @options, @
|
11
|
+
@type, @name, @options, @query_options, @original_options = type, name, {}, {}, options
|
12
12
|
options.symbolize_keys!
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
options.each_pair do |key, value|
|
17
|
-
if AssociationOptions.include?(key)
|
18
|
-
@options[key] = value
|
19
|
-
else
|
20
|
-
@finder_options[key] = value
|
21
|
-
end
|
22
|
-
end
|
13
|
+
options[:extend] = modularized_extensions(extension, options[:extend])
|
14
|
+
separate_options_and_conditions
|
23
15
|
end
|
24
16
|
|
25
17
|
def class_name
|
26
|
-
@class_name
|
18
|
+
return @class_name if defined?(@class_name)
|
19
|
+
|
20
|
+
@class_name =
|
27
21
|
if cn = options[:class_name]
|
28
22
|
cn
|
29
23
|
elsif many?
|
@@ -31,7 +25,6 @@ module MongoMapper
|
|
31
25
|
else
|
32
26
|
name.to_s.camelize
|
33
27
|
end
|
34
|
-
end
|
35
28
|
end
|
36
29
|
|
37
30
|
def klass
|
@@ -39,15 +32,15 @@ module MongoMapper
|
|
39
32
|
end
|
40
33
|
|
41
34
|
def many?
|
42
|
-
@
|
35
|
+
@type == :many
|
43
36
|
end
|
44
37
|
|
45
38
|
def belongs_to?
|
46
|
-
@
|
39
|
+
@type == :belongs_to
|
47
40
|
end
|
48
41
|
|
49
42
|
def one?
|
50
|
-
@
|
43
|
+
@type == :one
|
51
44
|
end
|
52
45
|
|
53
46
|
def polymorphic?
|
@@ -67,7 +60,7 @@ module MongoMapper
|
|
67
60
|
end
|
68
61
|
|
69
62
|
def type_key_name
|
70
|
-
|
63
|
+
many? ? '_type' : "#{as}_type"
|
71
64
|
end
|
72
65
|
|
73
66
|
def as
|
@@ -82,10 +75,13 @@ module MongoMapper
|
|
82
75
|
@ivar ||= "@_#{name}"
|
83
76
|
end
|
84
77
|
|
78
|
+
# hate this, need to revisit
|
85
79
|
def proxy_class
|
86
|
-
@proxy_class
|
80
|
+
return @proxy_class if defined?(@proxy_class)
|
81
|
+
|
82
|
+
@proxy_class =
|
87
83
|
if many?
|
88
|
-
if
|
84
|
+
if klass.embeddable?
|
89
85
|
polymorphic? ? ManyEmbeddedPolymorphicProxy : ManyEmbeddedProxy
|
90
86
|
else
|
91
87
|
if polymorphic?
|
@@ -103,14 +99,20 @@ module MongoMapper
|
|
103
99
|
else
|
104
100
|
polymorphic? ? BelongsToPolymorphicProxy : BelongsToProxy
|
105
101
|
end
|
106
|
-
end
|
107
102
|
end
|
108
103
|
|
109
104
|
private
|
105
|
+
def separate_options_and_conditions
|
106
|
+
@original_options.each_pair do |key, value|
|
107
|
+
if AssociationOptions.include?(key)
|
108
|
+
@options[key] = value
|
109
|
+
else
|
110
|
+
@query_options[key] = value
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
110
114
|
|
111
|
-
|
112
|
-
# Procs that extend the behaviour of this association.
|
113
|
-
def modulized_extensions(*extensions)
|
115
|
+
def modularized_extensions(*extensions)
|
114
116
|
extensions.flatten.compact.map do |extension|
|
115
117
|
Proc === extension ? Module.new(&extension) : extension
|
116
118
|
end
|
@@ -10,19 +10,19 @@ module MongoMapper
|
|
10
10
|
id, type = doc.id, doc.class.name
|
11
11
|
end
|
12
12
|
|
13
|
-
owner[
|
14
|
-
owner[
|
13
|
+
owner[association.foreign_key] = id
|
14
|
+
owner[association.type_key_name] = type
|
15
15
|
reset
|
16
16
|
end
|
17
17
|
|
18
18
|
protected
|
19
19
|
def find_target
|
20
|
-
return nil if association_class.nil? || owner[
|
21
|
-
association_class.find_by_id(owner[
|
20
|
+
return nil if association_class.nil? || owner[association.foreign_key].nil?
|
21
|
+
association_class.find_by_id(owner[association.foreign_key])
|
22
22
|
end
|
23
23
|
|
24
24
|
def association_class
|
25
|
-
proxy_owner[
|
25
|
+
proxy_owner[association.type_key_name] ? proxy_owner[association.type_key_name].constantize : nil
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
@@ -10,14 +10,14 @@ module MongoMapper
|
|
10
10
|
id = doc.id
|
11
11
|
end
|
12
12
|
|
13
|
-
owner[
|
13
|
+
owner[association.foreign_key] = id
|
14
14
|
reset
|
15
15
|
end
|
16
16
|
|
17
17
|
protected
|
18
18
|
def find_target
|
19
|
-
return nil if owner[
|
20
|
-
klass.find_by_id(owner[
|
19
|
+
return nil if owner[association.foreign_key].nil?
|
20
|
+
klass.find_by_id(owner[association.foreign_key])
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -78,7 +78,7 @@ module MongoMapper
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def nullify
|
81
|
-
criteria =
|
81
|
+
criteria = Query.new(klass, scoped_conditions).criteria
|
82
82
|
all(criteria).each do |doc|
|
83
83
|
doc.update_attributes(self.foreign_key => nil)
|
84
84
|
end
|
@@ -91,7 +91,7 @@ module MongoMapper
|
|
91
91
|
end
|
92
92
|
|
93
93
|
def scoped_options(options)
|
94
|
-
|
94
|
+
association.query_options.merge(options).merge(scoped_conditions)
|
95
95
|
end
|
96
96
|
|
97
97
|
def find_target
|
@@ -4,7 +4,7 @@ module MongoMapper
|
|
4
4
|
class ManyEmbeddedPolymorphicProxy < EmbeddedCollection
|
5
5
|
def replace(values)
|
6
6
|
@_values = values.map do |v|
|
7
|
-
v.respond_to?(:attributes) ? v.attributes.merge(
|
7
|
+
v.respond_to?(:attributes) ? v.attributes.merge(association.type_key_name => v.class.name) : v
|
8
8
|
end
|
9
9
|
reset
|
10
10
|
end
|
@@ -19,7 +19,7 @@ module MongoMapper
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def polymorphic_class(doc)
|
22
|
-
if class_name = doc[
|
22
|
+
if class_name = doc[association.type_key_name]
|
23
23
|
class_name.constantize
|
24
24
|
else
|
25
25
|
klass
|
@@ -46,7 +46,7 @@ module MongoMapper
|
|
46
46
|
|
47
47
|
protected
|
48
48
|
def find_target
|
49
|
-
target_class.first(
|
49
|
+
target_class.first(association.query_options.merge(foreign_key => owner.id))
|
50
50
|
end
|
51
51
|
|
52
52
|
def instantiate_target(instantiator, attrs={})
|
@@ -56,7 +56,7 @@ module MongoMapper
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def target_class
|
59
|
-
@target_class ||= options[:class] || (options[:class_name] ||
|
59
|
+
@target_class ||= options[:class] || (options[:class_name] || association.name.to_s.camelize).constantize
|
60
60
|
end
|
61
61
|
|
62
62
|
def foreign_key
|
@@ -7,19 +7,19 @@ module MongoMapper
|
|
7
7
|
|
8
8
|
instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|proxy_|^object_id$)/ }
|
9
9
|
|
10
|
-
attr_reader :owner, :
|
10
|
+
attr_reader :owner, :association, :target
|
11
11
|
|
12
12
|
alias :proxy_owner :owner
|
13
13
|
alias :proxy_target :target
|
14
|
-
alias :
|
14
|
+
alias :proxy_association :association
|
15
15
|
|
16
|
-
delegate :klass, :to => :
|
17
|
-
delegate :options, :to => :
|
16
|
+
delegate :klass, :to => :proxy_association
|
17
|
+
delegate :options, :to => :proxy_association
|
18
18
|
delegate :collection, :to => :klass
|
19
19
|
|
20
|
-
def initialize(owner,
|
21
|
-
@owner, @
|
22
|
-
Array(
|
20
|
+
def initialize(owner, association)
|
21
|
+
@owner, @association, @loaded = owner, association, false
|
22
|
+
Array(association.options[:extend]).each { |ext| proxy_extend(ext) }
|
23
23
|
reset
|
24
24
|
end
|
25
25
|
|
@@ -66,7 +66,7 @@ module MongoMapper
|
|
66
66
|
def associations
|
67
67
|
self.class.associations
|
68
68
|
end
|
69
|
-
|
69
|
+
|
70
70
|
# @api private?
|
71
71
|
def embedded_associations
|
72
72
|
associations.select do |name, association|
|
@@ -81,24 +81,25 @@ module MongoMapper
|
|
81
81
|
proxy = association.proxy_class.new(self, association)
|
82
82
|
self.instance_variable_set(association.ivar, proxy)
|
83
83
|
end
|
84
|
-
|
84
|
+
|
85
85
|
proxy
|
86
86
|
end
|
87
87
|
end
|
88
|
+
|
89
|
+
autoload :Base, 'mongo_mapper/plugins/associations/base'
|
90
|
+
autoload :Collection, 'mongo_mapper/plugins/associations/collection'
|
91
|
+
autoload :EmbeddedCollection, 'mongo_mapper/plugins/associations/embedded_collection'
|
92
|
+
autoload :ManyDocumentsProxy, 'mongo_mapper/plugins/associations/many_documents_proxy'
|
93
|
+
autoload :BelongsToProxy, 'mongo_mapper/plugins/associations/belongs_to_proxy'
|
94
|
+
autoload :BelongsToPolymorphicProxy, 'mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy'
|
95
|
+
autoload :ManyPolymorphicProxy, 'mongo_mapper/plugins/associations/many_polymorphic_proxy'
|
96
|
+
autoload :ManyEmbeddedProxy, 'mongo_mapper/plugins/associations/many_embedded_proxy'
|
97
|
+
autoload :ManyEmbeddedPolymorphicProxy, 'mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy'
|
98
|
+
autoload :ManyDocumentsAsProxy, 'mongo_mapper/plugins/associations/many_documents_as_proxy'
|
99
|
+
autoload :OneProxy, 'mongo_mapper/plugins/associations/one_proxy'
|
100
|
+
autoload :InArrayProxy, 'mongo_mapper/plugins/associations/in_array_proxy'
|
88
101
|
end
|
89
102
|
end
|
90
103
|
end
|
91
104
|
|
92
|
-
require 'mongo_mapper/plugins/associations/
|
93
|
-
require 'mongo_mapper/plugins/associations/proxy'
|
94
|
-
require 'mongo_mapper/plugins/associations/collection'
|
95
|
-
require 'mongo_mapper/plugins/associations/embedded_collection'
|
96
|
-
require 'mongo_mapper/plugins/associations/many_documents_proxy'
|
97
|
-
require 'mongo_mapper/plugins/associations/belongs_to_proxy'
|
98
|
-
require 'mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy'
|
99
|
-
require 'mongo_mapper/plugins/associations/many_polymorphic_proxy'
|
100
|
-
require 'mongo_mapper/plugins/associations/many_embedded_proxy'
|
101
|
-
require 'mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy'
|
102
|
-
require 'mongo_mapper/plugins/associations/many_documents_as_proxy'
|
103
|
-
require 'mongo_mapper/plugins/associations/one_proxy'
|
104
|
-
require 'mongo_mapper/plugins/associations/in_array_proxy'
|
105
|
+
require 'mongo_mapper/plugins/associations/proxy'
|
@@ -28,21 +28,21 @@ module MongoMapper
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def find_one(options={})
|
31
|
-
criteria,
|
31
|
+
criteria, query_options = to_query(options)
|
32
32
|
|
33
33
|
if simple_find?(criteria) && identity_map.key?(criteria[:_id])
|
34
34
|
identity_map[criteria[:_id]]
|
35
35
|
else
|
36
36
|
super.tap do |document|
|
37
|
-
remove_documents_from_map(document) if selecting_fields?(
|
37
|
+
remove_documents_from_map(document) if selecting_fields?(query_options)
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
42
|
def find_many(options)
|
43
|
-
criteria,
|
43
|
+
criteria, query_options = to_query(options)
|
44
44
|
super.tap do |documents|
|
45
|
-
remove_documents_from_map(documents) if selecting_fields?(
|
45
|
+
remove_documents_from_map(documents) if selecting_fields?(query_options)
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module MongoMapper
|
2
|
+
module Plugins
|
3
|
+
module Pagination
|
4
|
+
class Proxy
|
5
|
+
instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|proxy_|^object_id$)/ }
|
6
|
+
|
7
|
+
attr_accessor :subject
|
8
|
+
attr_reader :total_entries, :per_page, :current_page
|
9
|
+
alias limit per_page
|
10
|
+
|
11
|
+
def initialize(total_entries, current_page, per_page=nil)
|
12
|
+
@total_entries = total_entries.to_i
|
13
|
+
self.per_page = per_page
|
14
|
+
self.current_page = current_page
|
15
|
+
end
|
16
|
+
|
17
|
+
def total_pages
|
18
|
+
(total_entries / per_page.to_f).ceil
|
19
|
+
end
|
20
|
+
|
21
|
+
def out_of_bounds?
|
22
|
+
current_page > total_pages
|
23
|
+
end
|
24
|
+
|
25
|
+
def previous_page
|
26
|
+
current_page > 1 ? (current_page - 1) : nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def next_page
|
30
|
+
current_page < total_pages ? (current_page + 1) : nil
|
31
|
+
end
|
32
|
+
|
33
|
+
def skip
|
34
|
+
(current_page - 1) * per_page
|
35
|
+
end
|
36
|
+
alias offset skip # for will paginate support
|
37
|
+
|
38
|
+
def send(method, *args, &block)
|
39
|
+
if respond_to?(method)
|
40
|
+
super
|
41
|
+
else
|
42
|
+
subject.send(method, *args, &block)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def ===(other)
|
47
|
+
other === subject
|
48
|
+
end
|
49
|
+
|
50
|
+
def method_missing(name, *args, &block)
|
51
|
+
@subject.send(name, *args, &block)
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
def per_page=(value)
|
56
|
+
value = 25 if value.blank?
|
57
|
+
@per_page = value.to_i
|
58
|
+
end
|
59
|
+
|
60
|
+
def current_page=(value)
|
61
|
+
value = value.to_i
|
62
|
+
value = 1 if value < 1
|
63
|
+
@current_page = value
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|