mongo_mapper-unstable 2010.2.9 → 2010.2.10

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.09
1
+ 2010.02.10
@@ -71,7 +71,7 @@ module MongoMapper
71
71
  end
72
72
 
73
73
  def find_each(options={})
74
- criteria, options = to_finder_options(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 = to_finder_options(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 = to_finder_options(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
- FinderOptions.new(self, options).criteria
344
+ Query.new(self, options).criteria
345
345
  end
346
346
 
347
- def to_finder_options(options={})
348
- FinderOptions.new(self, options).to_a
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, :finder_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, @finder_options = type, name, {}, {}
11
+ @type, @name, @options, @query_options, @original_options = type, name, {}, {}, options
12
12
  options.symbolize_keys!
13
-
14
- options[:extend] = modulized_extensions(extension, options[:extend])
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 ||= begin
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
- @many_type ||= @type == :many
35
+ @type == :many
43
36
  end
44
37
 
45
38
  def belongs_to?
46
- @belongs_to_type ||= @type == :belongs_to
39
+ @type == :belongs_to
47
40
  end
48
41
 
49
42
  def one?
50
- @one_type ||= @type == :one
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
- @type_key_name ||= many? ? '_type' : "#{as}_type"
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 ||= begin
80
+ return @proxy_class if defined?(@proxy_class)
81
+
82
+ @proxy_class =
87
83
  if many?
88
- if self.klass.embeddable?
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
- # @param [Array<Module, Proc>] extensions a collection of Modules or
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[reflection.foreign_key] = id
14
- owner[reflection.type_key_name] = type
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[reflection.foreign_key].nil?
21
- association_class.find_by_id(owner[reflection.foreign_key])
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[reflection.type_key_name] ? proxy_owner[reflection.type_key_name].constantize : nil
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[reflection.foreign_key] = id
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[reflection.foreign_key].nil?
20
- klass.find_by_id(owner[reflection.foreign_key])
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
@@ -119,7 +119,7 @@ module MongoMapper
119
119
  end
120
120
 
121
121
  def scoped_options(options)
122
- reflection.finder_options.merge(options).merge(scoped_conditions)
122
+ association.query_options.merge(options).merge(scoped_conditions)
123
123
  end
124
124
 
125
125
  def scoped_ids(args)
@@ -78,7 +78,7 @@ module MongoMapper
78
78
  end
79
79
 
80
80
  def nullify
81
- criteria = FinderOptions.new(klass, scoped_conditions).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
- reflection.finder_options.merge(options).merge(scoped_conditions)
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(reflection.type_key_name => v.class.name) : v
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[reflection.type_key_name]
22
+ if class_name = doc[association.type_key_name]
23
23
  class_name.constantize
24
24
  else
25
25
  klass
@@ -4,7 +4,7 @@ module MongoMapper
4
4
  class ManyPolymorphicProxy < ManyDocumentsProxy
5
5
  private
6
6
  def apply_scope(doc)
7
- doc[reflection.type_key_name] = doc.class.name
7
+ doc[association.type_key_name] = doc.class.name
8
8
  super
9
9
  end
10
10
  end
@@ -46,7 +46,7 @@ module MongoMapper
46
46
 
47
47
  protected
48
48
  def find_target
49
- target_class.first(reflection.finder_options.merge(foreign_key => owner.id))
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] || reflection.name.to_s.camelize).constantize
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, :reflection, :target
10
+ attr_reader :owner, :association, :target
11
11
 
12
12
  alias :proxy_owner :owner
13
13
  alias :proxy_target :target
14
- alias :proxy_reflection :reflection
14
+ alias :proxy_association :association
15
15
 
16
- delegate :klass, :to => :proxy_reflection
17
- delegate :options, :to => :proxy_reflection
16
+ delegate :klass, :to => :proxy_association
17
+ delegate :options, :to => :proxy_association
18
18
  delegate :collection, :to => :klass
19
19
 
20
- def initialize(owner, reflection)
21
- @owner, @reflection, @loaded = owner, reflection, false
22
- Array(reflection.options[:extend]).each { |ext| proxy_extend(ext) }
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/base'
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, finder_options = to_finder_options(options)
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?(finder_options)
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, finder_options = to_finder_options(options)
43
+ criteria, query_options = to_query(options)
44
44
  super.tap do |documents|
45
- remove_documents_from_map(documents) if selecting_fields?(finder_options)
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