mongo_mapper 0.6.6 → 0.6.7

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 CHANGED
@@ -1 +1 @@
1
- 0.6.6
1
+ 0.6.7
data/lib/mongo_mapper.rb CHANGED
@@ -67,31 +67,6 @@ module MongoMapper
67
67
  end
68
68
  end
69
69
 
70
- # @api private
71
- module Finders
72
- def dynamic_find(finder, args)
73
- attributes = {}
74
- finder.attributes.each_with_index do |attr, index|
75
- attributes[attr] = args[index]
76
- end
77
-
78
- options = args.extract_options!.merge(attributes)
79
- result = find(finder.finder, options)
80
-
81
- if result.nil?
82
- if finder.bang
83
- raise DocumentNotFound, "Couldn't find Document with #{attributes.inspect} in collection named #{collection.name}"
84
- end
85
-
86
- if finder.instantiator
87
- self.send(finder.instantiator, attributes)
88
- end
89
- else
90
- result
91
- end
92
- end
93
- end
94
-
95
70
  # @api private
96
71
  def self.use_time_zone?
97
72
  Time.respond_to?(:zone) && Time.zone ? true : false
@@ -102,23 +77,13 @@ module MongoMapper
102
77
  use_time_zone? ? Time.zone : Time
103
78
  end
104
79
 
80
+ # @api private
105
81
  def self.normalize_object_id(value)
106
82
  value.is_a?(String) ? Mongo::ObjectID.from_string(value) : value
107
83
  end
108
84
  end
109
85
 
110
86
  require 'mongo_mapper/support'
111
- require 'mongo_mapper/associations'
112
- require 'mongo_mapper/associations/base'
113
- require 'mongo_mapper/associations/proxy'
114
- require 'mongo_mapper/associations/many_documents_proxy'
115
- require 'mongo_mapper/associations/belongs_to_proxy'
116
- require 'mongo_mapper/associations/belongs_to_polymorphic_proxy'
117
- require 'mongo_mapper/associations/many_proxy'
118
- require 'mongo_mapper/associations/many_polymorphic_proxy'
119
- require 'mongo_mapper/associations/many_embedded_proxy'
120
- require 'mongo_mapper/associations/many_embedded_polymorphic_proxy'
121
- require 'mongo_mapper/associations/many_documents_as_proxy'
122
87
  require 'mongo_mapper/callbacks'
123
88
  require 'mongo_mapper/finder_options'
124
89
  require 'mongo_mapper/dirty'
@@ -132,3 +97,14 @@ require 'mongo_mapper/rails_compatibility/document'
132
97
  require 'mongo_mapper/rails_compatibility/embedded_document'
133
98
  require 'mongo_mapper/embedded_document'
134
99
  require 'mongo_mapper/document'
100
+ require 'mongo_mapper/associations'
101
+ require 'mongo_mapper/associations/base'
102
+ require 'mongo_mapper/associations/proxy'
103
+ require 'mongo_mapper/associations/collection'
104
+ require 'mongo_mapper/associations/many_documents_proxy'
105
+ require 'mongo_mapper/associations/belongs_to_proxy'
106
+ require 'mongo_mapper/associations/belongs_to_polymorphic_proxy'
107
+ require 'mongo_mapper/associations/many_polymorphic_proxy'
108
+ require 'mongo_mapper/associations/many_embedded_proxy'
109
+ require 'mongo_mapper/associations/many_embedded_polymorphic_proxy'
110
+ require 'mongo_mapper/associations/many_documents_as_proxy'
@@ -87,7 +87,7 @@ module MongoMapper
87
87
  elsif as?
88
88
  ManyDocumentsAsProxy
89
89
  else
90
- ManyProxy
90
+ ManyDocumentsProxy
91
91
  end
92
92
  end
93
93
  else
@@ -4,30 +4,22 @@ module MongoMapper
4
4
  def replace(doc)
5
5
  if doc
6
6
  doc.save if doc.new?
7
- id, type = doc._id, doc.class.name
7
+ id, type = doc.id, doc.class.name
8
8
  end
9
9
 
10
- @owner.send("#{@association.foreign_key}=", id)
11
- @owner.send("#{@association.type_key_name}=", type)
10
+ owner[reflection.foreign_key] = id
11
+ owner[reflection.type_key_name] = type
12
12
  reset
13
13
  end
14
14
 
15
15
  protected
16
16
  def find_target
17
- if proxy_id && proxy_class
18
- proxy_class.find_by_id(proxy_id)
19
- end
17
+ return nil if association_class.nil? || owner[reflection.foreign_key].nil?
18
+ association_class.first(:id => owner[reflection.foreign_key])
20
19
  end
21
20
 
22
- def proxy_id
23
- @proxy_id ||= @owner.send(@association.foreign_key)
24
- end
25
-
26
- def proxy_class
27
- @proxy_class ||= begin
28
- klass = @owner.send(@association.type_key_name)
29
- klass && klass.constantize
30
- end
21
+ def association_class
22
+ proxy_owner[reflection.type_key_name] ? proxy_owner[reflection.type_key_name].constantize : nil
31
23
  end
32
24
  end
33
25
  end
@@ -4,18 +4,17 @@ module MongoMapper
4
4
  def replace(doc)
5
5
  if doc
6
6
  doc.save if doc.new?
7
- id = doc._id
7
+ id = doc.id
8
8
  end
9
-
10
- @owner.send("#{@association.foreign_key}=", id)
9
+
10
+ owner[reflection.foreign_key] = id
11
11
  reset
12
12
  end
13
13
 
14
14
  protected
15
15
  def find_target
16
- if association_id = @owner.send(@association.foreign_key)
17
- @association.klass.find_by_id(association_id)
18
- end
16
+ return nil if owner[reflection.foreign_key].nil?
17
+ klass.first(:id => owner[reflection.foreign_key])
19
18
  end
20
19
  end
21
20
  end
@@ -0,0 +1,19 @@
1
+ module MongoMapper
2
+ module Associations
3
+ class Collection < Proxy
4
+ def to_ary
5
+ load_target
6
+ if target.is_a?(Array)
7
+ target.to_ary
8
+ else
9
+ Array(target)
10
+ end
11
+ end
12
+
13
+ def reset
14
+ super
15
+ target = []
16
+ end
17
+ end
18
+ end
19
+ end
@@ -3,22 +3,23 @@ module MongoMapper
3
3
  class ManyDocumentsAsProxy < ManyDocumentsProxy
4
4
  protected
5
5
  def scoped_conditions
6
- {as_type_name => @owner.class.name, as_id_name => @owner._id}
6
+ {type_key_name => owner.class.name, id_key_name => owner.id}
7
7
  end
8
8
 
9
9
  def apply_scope(doc)
10
10
  ensure_owner_saved
11
- doc.send("#{as_type_name}=", @owner.class.name)
12
- doc.send("#{as_id_name}=", @owner._id)
11
+ doc[type_key_name] = owner.class.name
12
+ doc[id_key_name] = owner.id
13
13
  doc
14
14
  end
15
-
16
- def as_type_name
17
- @as_type_name ||= @association.options[:as].to_s + "_type"
15
+
16
+ private
17
+ def type_key_name
18
+ "#{options[:as]}_type"
18
19
  end
19
-
20
- def as_id_name
21
- @as_id_name ||= @association.options[:as].to_s + "_id"
20
+
21
+ def id_key_name
22
+ "#{options[:as]}_id"
22
23
  end
23
24
  end
24
25
  end
@@ -1,9 +1,6 @@
1
1
  module MongoMapper
2
2
  module Associations
3
- class ManyDocumentsProxy < Proxy
4
- delegate :klass, :to => :@association
5
- delegate :collection, :to => :klass
6
-
3
+ class ManyDocumentsProxy < Collection
7
4
  include ::MongoMapper::Finders
8
5
 
9
6
  def find(*args)
@@ -37,7 +34,8 @@ module MongoMapper
37
34
  end
38
35
 
39
36
  def replace(docs)
40
- @target.map(&:destroy) if load_target
37
+ load_target
38
+ target.map(&:destroy)
41
39
  docs.each { |doc| apply_scope(doc).save }
42
40
  reset
43
41
  end
@@ -85,24 +83,14 @@ module MongoMapper
85
83
  end
86
84
  reset
87
85
  end
88
-
89
- def method_missing(method, *args)
90
- finder = DynamicFinder.new(method)
91
-
92
- if finder.found?
93
- dynamic_find(finder, args)
94
- else
95
- super
96
- end
97
- end
98
-
86
+
99
87
  protected
100
88
  def scoped_conditions
101
- {self.foreign_key => @owner._id}
89
+ {self.foreign_key => owner.id}
102
90
  end
103
91
 
104
92
  def scoped_options(options)
105
- @association.finder_options.merge(options).merge(scoped_conditions)
93
+ reflection.finder_options.merge(options).merge(scoped_conditions)
106
94
  end
107
95
 
108
96
  def find_target
@@ -110,17 +98,17 @@ module MongoMapper
110
98
  end
111
99
 
112
100
  def ensure_owner_saved
113
- @owner.save if @owner.new?
101
+ owner.save if owner.new?
114
102
  end
115
103
 
116
104
  def apply_scope(doc)
117
105
  ensure_owner_saved
118
- doc.send("#{self.foreign_key}=", @owner._id)
106
+ doc[foreign_key] = owner.id
119
107
  doc
120
108
  end
121
109
 
122
110
  def foreign_key
123
- @association.options[:foreign_key] || @owner.class.name.underscore.gsub("/", "_") + "_id"
111
+ options[:foreign_key] || owner.class.name.underscore.gsub("/", "_") + "_id"
124
112
  end
125
113
  end
126
114
  end
@@ -1,16 +1,14 @@
1
1
  module MongoMapper
2
2
  module Associations
3
- class ManyEmbeddedPolymorphicProxy < Proxy
4
- def replace(v)
5
- @_values = v.map do |doc_or_hash|
6
- if doc_or_hash.kind_of?(EmbeddedDocument)
7
- doc = doc_or_hash
8
- {@association.type_key_name => doc.class.name}.merge(doc.attributes)
3
+ class ManyEmbeddedPolymorphicProxy < Collection
4
+ def replace(values)
5
+ @_values = values.map do |v|
6
+ if v.kind_of?(EmbeddedDocument)
7
+ v.attributes.merge(reflection.type_key_name => v.class.name)
9
8
  else
10
- doc_or_hash
9
+ v
11
10
  end
12
11
  end
13
-
14
12
  reset
15
13
  end
16
14
 
@@ -22,10 +20,10 @@ module MongoMapper
22
20
  end
23
21
 
24
22
  def polymorphic_class(doc)
25
- if class_name = doc[@association.type_key_name]
23
+ if class_name = doc[reflection.type_key_name]
26
24
  class_name.constantize
27
25
  else
28
- @association.klass
26
+ klass
29
27
  end
30
28
  end
31
29
  end
@@ -1,13 +1,15 @@
1
1
  module MongoMapper
2
2
  module Associations
3
- class ManyEmbeddedProxy < Proxy
4
- def replace(v)
5
- @_values = v.map { |e| e.kind_of?(EmbeddedDocument) ? e.attributes : e }
3
+ class ManyEmbeddedProxy < Collection
4
+ def replace(values)
5
+ @_values = values.map do |v|
6
+ v.kind_of?(EmbeddedDocument) ? v.attributes : v
7
+ end
6
8
  reset
7
9
  end
8
10
 
9
11
  def build(attributes={})
10
- doc = @association.klass.new(attributes)
12
+ doc = klass.new(attributes)
11
13
  assign_root_document(doc)
12
14
  self << doc
13
15
  doc
@@ -16,15 +18,14 @@ module MongoMapper
16
18
  # TODO: test that both string and oid version work
17
19
  def find(id)
18
20
  load_target
19
- @target.detect { |item| item.id.to_s == id || item.id == id }
21
+ target.detect { |item| item.id.to_s == id || item.id == id }
20
22
  end
21
23
 
22
24
  def <<(*docs)
23
- if load_target
24
- docs.each do |doc|
25
- assign_root_document(doc)
26
- @target << doc
27
- end
25
+ load_target
26
+ docs.each do |doc|
27
+ assign_root_document(doc)
28
+ target << doc
28
29
  end
29
30
  end
30
31
  alias_method :push, :<<
@@ -32,15 +33,15 @@ module MongoMapper
32
33
 
33
34
  private
34
35
  def find_target
35
- (@_values || []).map do |e|
36
- child = @association.klass.new(e)
36
+ (@_values || []).map do |v|
37
+ child = klass.new(v)
37
38
  assign_root_document(child)
38
39
  child
39
40
  end
40
41
  end
41
42
 
42
43
  def root_document
43
- @owner._root_document || @owner
44
+ owner._root_document || owner
44
45
  end
45
46
 
46
47
  def assign_root_document(*docs)
@@ -3,7 +3,7 @@ module MongoMapper
3
3
  class ManyPolymorphicProxy < ManyDocumentsProxy
4
4
  private
5
5
  def apply_scope(doc)
6
- doc.send("#{@association.type_key_name}=", doc.class.name)
6
+ doc[reflection.type_key_name] = doc.class.name
7
7
  super
8
8
  end
9
9
  end
@@ -1,67 +1,100 @@
1
1
  module MongoMapper
2
2
  module Associations
3
- class Proxy < BasicObject
4
- attr_reader :owner, :association
3
+ class Proxy
4
+ alias :proxy_respond_to? :respond_to?
5
+ alias :proxy_extend :extend
5
6
 
6
- def initialize(owner, association)
7
- @owner = owner
8
- @association = association
9
- @association.options[:extend].each { |ext| class << self; self; end.instance_eval { include ext } }
7
+ instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|proxy_|^object_id$)/ }
8
+
9
+ attr_reader :owner, :reflection, :target
10
+
11
+ alias :proxy_owner :owner
12
+ alias :proxy_target :target
13
+ alias :proxy_reflection :reflection
14
+
15
+ delegate :klass, :to => :proxy_reflection
16
+ delegate :options, :to => :proxy_reflection
17
+ delegate :collection, :to => :klass
18
+
19
+ def initialize(owner, reflection)
20
+ @owner, @reflection = owner, reflection
21
+ Array(reflection.options[:extend]).each { |ext| proxy_extend(ext) }
10
22
  reset
11
23
  end
12
-
13
- def respond_to?(*methods)
14
- (load_target && @target.respond_to?(*methods))
24
+
25
+ def inspect
26
+ load_target
27
+ target.inspect
15
28
  end
16
-
17
- def reset
18
- @target = nil
29
+
30
+ def loaded?
31
+ @loaded
19
32
  end
20
-
21
- def reload_target
22
- reset
33
+
34
+ def loaded
35
+ @loaded = true
36
+ end
37
+
38
+ def nil?
23
39
  load_target
24
- self
40
+ target.nil?
25
41
  end
26
-
27
- def send(method, *args)
28
- metaclass_instance_methods = class << self; self; end.instance_methods
29
-
30
- if metaclass_instance_methods.any? { |m| m.to_s == method.to_s }
31
- return __send__(method, *args)
32
- end
33
-
42
+
43
+ def blank?
34
44
  load_target
35
- @target.send(method, *args)
45
+ target.blank?
36
46
  end
37
-
47
+
48
+ def reload
49
+ reset
50
+ load_target
51
+ self unless target.nil?
52
+ end
53
+
38
54
  def replace(v)
39
55
  raise NotImplementedError
40
56
  end
41
-
42
- def inspect
43
- load_target
44
- @target.inspect
57
+
58
+ def reset
59
+ @loaded = false
60
+ target = nil
61
+ end
62
+
63
+ def respond_to?(*args)
64
+ proxy_respond_to?(*args) || (load_target && target.respond_to?(*args))
65
+ end
66
+
67
+ def send(method, *args)
68
+ if proxy_respond_to?(method)
69
+ super
70
+ else
71
+ load_target
72
+ target.send(method, *args)
73
+ end
45
74
  end
46
75
 
47
- def nil?
76
+ def ===(other)
48
77
  load_target
49
- @target.nil?
78
+ other === target
50
79
  end
51
80
 
52
81
  protected
53
82
  def method_missing(method, *args, &block)
54
83
  if load_target
55
- if block.nil?
56
- @target.send(method, *args)
84
+ if block_given?
85
+ target.send(method, *args) { |*block_args| block.call(*block_args) }
57
86
  else
58
- @target.send(method, *args) { |*block_args| block.call(*block_args) }
87
+ target.send(method, *args)
59
88
  end
60
89
  end
61
90
  end
62
91
 
63
92
  def load_target
64
- @target ||= find_target
93
+ @target = find_target unless loaded?
94
+ loaded
95
+ @target
96
+ rescue MongoMapper::DocumentNotFound
97
+ reset
65
98
  end
66
99
 
67
100
  def find_target
@@ -316,18 +316,6 @@ module MongoMapper
316
316
  superclass.respond_to?(:keys) && superclass.keys.has_key?('_type')
317
317
  end
318
318
 
319
- protected
320
- def method_missing(method, *args)
321
- finder = DynamicFinder.new(method)
322
-
323
- if finder.found?
324
- meta_def(finder.method) { |*args| dynamic_find(finder, args) }
325
- send(finder.method, *args)
326
- else
327
- super
328
- end
329
- end
330
-
331
319
  private
332
320
  def create_indexes_for(key)
333
321
  ensure_index key.name if key.options[:index]
@@ -438,7 +426,10 @@ module MongoMapper
438
426
  end
439
427
 
440
428
  def reload
441
- self.class.find(_id)
429
+ doc = self.class.find(_id)
430
+ self.class.associations.each { |name, assoc| send(name).reset }
431
+ self.attributes = doc.attributes
432
+ self
442
433
  end
443
434
 
444
435
  private
@@ -1,4 +1,39 @@
1
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 = find(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
+
2
37
  class DynamicFinder
3
38
  attr_reader :method, :attributes, :finder, :bang, :instantiator
4
39
 
@@ -6,12 +41,16 @@ module MongoMapper
6
41
  @method = method
7
42
  @finder = :first
8
43
  @bang = false
9
- match()
44
+ match
10
45
  end
11
46
 
12
47
  def found?
13
48
  @finder.present?
14
49
  end
50
+
51
+ def raise?
52
+ bang == true
53
+ end
15
54
 
16
55
  protected
17
56
  def match
@@ -1,6 +1,8 @@
1
1
  module MongoMapper
2
2
  module Pagination
3
- class PaginationProxy < BasicObject
3
+ class PaginationProxy
4
+ instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|proxy_|^object_id$)/ }
5
+
4
6
  attr_accessor :subject
5
7
  attr_reader :total_entries, :per_page, :current_page
6
8
  alias limit per_page
@@ -1,9 +1,5 @@
1
1
  require 'set'
2
2
 
3
- class BasicObject #:nodoc:
4
- instance_methods.each { |m| undef_method m unless m =~ /(^__|instance_eval)/ }
5
- end unless defined?(BasicObject)
6
-
7
3
  class Array
8
4
  def self.to_mongo(value)
9
5
  value = value.respond_to?(:lines) ? value.lines : value
@@ -32,7 +32,7 @@ module MongoMapper
32
32
  def where_conditions(instance)
33
33
  conditions = {}
34
34
  unless case_sensitive
35
- conditions.merge!({'$where' => "this.#{attribute}.toLowerCase() == '#{instance[attribute].downcase}'"})
35
+ conditions.merge!({'$where' => "this.#{attribute}.toLowerCase() == '#{instance[attribute].to_s.downcase}'"})
36
36
  end
37
37
  conditions
38
38
  end
data/mongo_mapper.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{mongo_mapper}
8
- s.version = "0.6.6"
8
+ s.version = "0.6.7"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["John Nunemaker"]
12
- s.date = %q{2009-12-05}
12
+ s.date = %q{2009-12-13}
13
13
  s.default_executable = %q{mmconsole}
14
14
  s.email = %q{nunemaker@gmail.com}
15
15
  s.executables = ["mmconsole"]
@@ -29,12 +29,12 @@ Gem::Specification.new do |s|
29
29
  "lib/mongo_mapper/associations/base.rb",
30
30
  "lib/mongo_mapper/associations/belongs_to_polymorphic_proxy.rb",
31
31
  "lib/mongo_mapper/associations/belongs_to_proxy.rb",
32
+ "lib/mongo_mapper/associations/collection.rb",
32
33
  "lib/mongo_mapper/associations/many_documents_as_proxy.rb",
33
34
  "lib/mongo_mapper/associations/many_documents_proxy.rb",
34
35
  "lib/mongo_mapper/associations/many_embedded_polymorphic_proxy.rb",
35
36
  "lib/mongo_mapper/associations/many_embedded_proxy.rb",
36
37
  "lib/mongo_mapper/associations/many_polymorphic_proxy.rb",
37
- "lib/mongo_mapper/associations/many_proxy.rb",
38
38
  "lib/mongo_mapper/associations/proxy.rb",
39
39
  "lib/mongo_mapper/callbacks.rb",
40
40
  "lib/mongo_mapper/dirty.rb",
@@ -57,10 +57,10 @@ Gem::Specification.new do |s|
57
57
  "test/functional/associations/test_belongs_to_polymorphic_proxy.rb",
58
58
  "test/functional/associations/test_belongs_to_proxy.rb",
59
59
  "test/functional/associations/test_many_documents_as_proxy.rb",
60
+ "test/functional/associations/test_many_documents_proxy.rb",
60
61
  "test/functional/associations/test_many_embedded_polymorphic_proxy.rb",
61
62
  "test/functional/associations/test_many_embedded_proxy.rb",
62
63
  "test/functional/associations/test_many_polymorphic_proxy.rb",
63
- "test/functional/associations/test_many_proxy.rb",
64
64
  "test/functional/test_associations.rb",
65
65
  "test/functional/test_binary.rb",
66
66
  "test/functional/test_callbacks.rb",
@@ -76,8 +76,9 @@ Gem::Specification.new do |s|
76
76
  "test/support/custom_matchers.rb",
77
77
  "test/support/timing.rb",
78
78
  "test/test_helper.rb",
79
+ "test/unit/associations/test_base.rb",
80
+ "test/unit/associations/test_proxy.rb",
79
81
  "test/unit/serializers/test_json_serializer.rb",
80
- "test/unit/test_association_base.rb",
81
82
  "test/unit/test_document.rb",
82
83
  "test/unit/test_dynamic_finder.rb",
83
84
  "test/unit/test_embedded_document.rb",
@@ -101,10 +102,10 @@ Gem::Specification.new do |s|
101
102
  "test/functional/associations/test_belongs_to_polymorphic_proxy.rb",
102
103
  "test/functional/associations/test_belongs_to_proxy.rb",
103
104
  "test/functional/associations/test_many_documents_as_proxy.rb",
105
+ "test/functional/associations/test_many_documents_proxy.rb",
104
106
  "test/functional/associations/test_many_embedded_polymorphic_proxy.rb",
105
107
  "test/functional/associations/test_many_embedded_proxy.rb",
106
108
  "test/functional/associations/test_many_polymorphic_proxy.rb",
107
- "test/functional/associations/test_many_proxy.rb",
108
109
  "test/functional/test_associations.rb",
109
110
  "test/functional/test_binary.rb",
110
111
  "test/functional/test_callbacks.rb",
@@ -120,8 +121,9 @@ Gem::Specification.new do |s|
120
121
  "test/support/custom_matchers.rb",
121
122
  "test/support/timing.rb",
122
123
  "test/test_helper.rb",
124
+ "test/unit/associations/test_base.rb",
125
+ "test/unit/associations/test_proxy.rb",
123
126
  "test/unit/serializers/test_json_serializer.rb",
124
- "test/unit/test_association_base.rb",
125
127
  "test/unit/test_document.rb",
126
128
  "test/unit/test_dynamic_finder.rb",
127
129
  "test/unit/test_embedded_document.rb",
@@ -1,7 +1,7 @@
1
1
  require 'test_helper'
2
2
  require 'models'
3
3
 
4
- class ManyProxyTest < Test::Unit::TestCase
4
+ class ManyDocumentsProxyTest < Test::Unit::TestCase
5
5
  def setup
6
6
  Project.collection.remove
7
7
  Status.collection.remove
@@ -37,16 +37,16 @@ class ManyProxyTest < Test::Unit::TestCase
37
37
  project.statuses.concat Status.new(:name => 'concat')
38
38
 
39
39
  project = project.reload
40
- project.statuses[0].project_id.should == project._id
41
- project.statuses[1].project_id.should == project._id
42
- project.statuses[2].project_id.should == project._id
40
+ project.statuses[0].project_id.should == project.id
41
+ project.statuses[1].project_id.should == project.id
42
+ project.statuses[2].project_id.should == project.id
43
43
  end
44
44
 
45
45
  context "build" do
46
46
  should "assign foreign key" do
47
47
  project = Project.create
48
48
  status = project.statuses.build
49
- status.project_id.should == project._id
49
+ status.project_id.should == project.id
50
50
  end
51
51
 
52
52
  should "allow assigning attributes" do
@@ -60,7 +60,7 @@ class ManyProxyTest < Test::Unit::TestCase
60
60
  should "assign foreign key" do
61
61
  project = Project.create
62
62
  status = project.statuses.create(:name => 'Foo!')
63
- status.project_id.should == project._id
63
+ status.project_id.should == project.id
64
64
  end
65
65
 
66
66
  should "save record" do
@@ -81,7 +81,7 @@ class ManyProxyTest < Test::Unit::TestCase
81
81
  should "assign foreign key" do
82
82
  project = Project.create
83
83
  status = project.statuses.create!(:name => 'Foo!')
84
- status.project_id.should == project._id
84
+ status.project_id.should == project.id
85
85
  end
86
86
 
87
87
  should "save record" do
@@ -205,11 +205,14 @@ class ManyProxyTest < Test::Unit::TestCase
205
205
  context "dynamic finders" do
206
206
  should "work with single key" do
207
207
  @project1.statuses.find_by_name('New').should == @brand_new
208
+ @project1.statuses.find_by_name!('New').should == @brand_new
208
209
  @project2.statuses.find_by_name('In Progress').should == @in_progress
210
+ @project2.statuses.find_by_name!('In Progress').should == @in_progress
209
211
  end
210
212
 
211
213
  should "work with multiple keys" do
212
214
  @project1.statuses.find_by_name_and_position('New', 1).should == @brand_new
215
+ @project1.statuses.find_by_name_and_position!('New', 1).should == @brand_new
213
216
  @project1.statuses.find_by_name_and_position('New', 2).should be_nil
214
217
  end
215
218
 
@@ -315,25 +318,25 @@ class ManyProxyTest < Test::Unit::TestCase
315
318
 
316
319
  context "with one id" do
317
320
  should "work for id in association" do
318
- @project1.statuses.find(@complete._id).should == @complete
321
+ @project1.statuses.find(@complete.id).should == @complete
319
322
  end
320
323
 
321
324
  should "not work for id not in association" do
322
325
  lambda {
323
- @project1.statuses.find!(@archived._id)
326
+ @project1.statuses.find!(@archived.id)
324
327
  }.should raise_error(MongoMapper::DocumentNotFound)
325
328
  end
326
329
  end
327
330
 
328
331
  context "with multiple ids" do
329
332
  should "work for ids in association" do
330
- statuses = @project1.statuses.find(@brand_new._id, @complete._id)
333
+ statuses = @project1.statuses.find(@brand_new.id, @complete.id)
331
334
  statuses.should == [@brand_new, @complete]
332
335
  end
333
336
 
334
337
  should "not work for ids not in association" do
335
338
  lambda {
336
- @project1.statuses.find!(@brand_new._id, @complete._id, @archived._id)
339
+ @project1.statuses.find!(@brand_new.id, @complete.id, @archived.id)
337
340
  }.should raise_error(MongoMapper::DocumentNotFound)
338
341
  end
339
342
  end
@@ -26,7 +26,7 @@ class ManyEmbeddedProxyTest < Test::Unit::TestCase
26
26
  project.addresses << chi
27
27
  project.save
28
28
 
29
- project = project.reload
29
+ project.reload
30
30
  project.addresses.size.should == 2
31
31
  project.addresses[0].should == sb
32
32
  project.addresses[1].should == chi
@@ -47,7 +47,7 @@ class ManyEmbeddedProxyTest < Test::Unit::TestCase
47
47
  doc = @document.new(:person => meg)
48
48
  doc.save
49
49
 
50
- doc = doc.reload
50
+ doc.reload
51
51
  doc.person.name.should == 'Meg'
52
52
  doc.person.child.name.should == 'Steve'
53
53
  doc.person.child.child.name.should == 'Linda'
@@ -70,7 +70,7 @@ class ManyEmbeddedProxyTest < Test::Unit::TestCase
70
70
  pet_lover.pets[1].species.should == "Siberian Husky"
71
71
  pet_lover.save.should be_true
72
72
 
73
- pet_lover = pet_lover.reload
73
+ pet_lover.reload
74
74
  pet_lover.name.should == "Mr. Pet Lover"
75
75
  pet_lover.pets[0].name.should == "Jimmy"
76
76
  pet_lover.pets[0].species.should == "Cocker Spainel"
@@ -89,19 +89,17 @@ class ManyEmbeddedProxyTest < Test::Unit::TestCase
89
89
  end
90
90
 
91
91
  should "persist all embedded documents" do
92
- meg = Person.new(:name => "Meg")
92
+ meg = Person.new(:name => "Meg")
93
93
  sparky = Pet.new(:name => "Sparky", :species => "Dog")
94
- koda = Pet.new(:name => "Koda", :species => "Dog")
94
+ koda = Pet.new(:name => "Koda", :species => "Dog")
95
95
 
96
96
  doc = @document.new
97
-
98
97
  meg.pets << sparky
99
98
  meg.pets << koda
100
-
101
99
  doc.people << meg
102
100
  doc.save
103
101
 
104
- doc = doc.reload
102
+ doc.reload
105
103
  doc.people.first.name.should == "Meg"
106
104
  doc.people.first.pets.should_not == []
107
105
  doc.people.first.pets.first.name.should == "Sparky"
@@ -111,11 +109,9 @@ class ManyEmbeddedProxyTest < Test::Unit::TestCase
111
109
  end
112
110
 
113
111
  should "create a reference to the root document for all embedded documents before save" do
114
- meg = Person.new(:name => "Meg")
112
+ meg = Person.new(:name => "Meg")
115
113
  sparky = Pet.new(:name => "Sparky", :species => "Dog")
116
-
117
- doc = @document.new
118
-
114
+ doc = @document.new
119
115
  doc.people << meg
120
116
  meg.pets << sparky
121
117
 
@@ -125,12 +121,12 @@ class ManyEmbeddedProxyTest < Test::Unit::TestCase
125
121
 
126
122
  should "create a reference to the root document for all embedded documents" do
127
123
  sparky = Pet.new(:name => "Sparky", :species => "Dog")
128
- meg = Person.new(:name => "Meg", :pets => [sparky])
129
- doc = @document.new
124
+ meg = Person.new(:name => "Meg", :pets => [sparky])
125
+ doc = @document.new
130
126
  doc.people << meg
131
127
  doc.save
132
128
 
133
- doc = doc.reload
129
+ doc.reload
134
130
  doc.people.first._root_document.should == doc
135
131
  doc.people.first.pets.first._root_document.should == doc
136
132
  end
@@ -40,5 +40,5 @@ class AssociationsTest < Test::Unit::TestCase
40
40
 
41
41
  post1 = post1.reload
42
42
  post1.tags.should == [tag1]
43
- end
43
+ end
44
44
  end
@@ -32,7 +32,9 @@ class DocumentTest < Test::Unit::TestCase
32
32
 
33
33
  should "not fail" do
34
34
  doc = @document.new(:file => nil)
35
- doc.save
35
+ lambda {
36
+ doc.save
37
+ }.should_not raise_error
36
38
  end
37
39
  end
38
40
 
@@ -1178,13 +1180,47 @@ class DocumentTest < Test::Unit::TestCase
1178
1180
 
1179
1181
  context "reload" do
1180
1182
  setup do
1181
- @doc_instance_1 = @document.create({:first_name => 'Ryan', :last_name => 'Koopmans', :age => '37'})
1182
- @doc_instance_2 = @document.update(@doc_instance_1._id, {:age => '39'})
1183
+ @foo_class = Class.new do
1184
+ include MongoMapper::Document
1185
+ key :name
1186
+ end
1187
+ @foo_class.collection.remove
1188
+
1189
+ @bar_class = Class.new do
1190
+ include MongoMapper::EmbeddedDocument
1191
+ key :name
1192
+ end
1193
+
1194
+ @document.many :foos, :class => @foo_class
1195
+ @document.many :bars, :class => @bar_class
1196
+
1197
+ @instance = @document.create({
1198
+ :age => 39,
1199
+ :foos => [@foo_class.new(:name => '1')],
1200
+ :bars => [@bar_class.new(:name => '1')],
1201
+ })
1183
1202
  end
1184
1203
 
1185
- should "load fresh information from the database" do
1186
- @doc_instance_1.age.should == 37
1187
- @doc_instance_1.reload.age.should == 39
1204
+ should "reload keys from the database" do
1205
+ @instance.age = 37
1206
+ @instance.age.should == 37
1207
+ @instance.reload
1208
+ @instance.age.should == 39
1209
+ end
1210
+
1211
+ should "reset all associations" do
1212
+ @instance.foos.expects(:reset).at_least_once
1213
+ @instance.bars.expects(:reset).at_least_once
1214
+ @instance.reload
1215
+ end
1216
+
1217
+ should "reinstantiate embedded associations" do
1218
+ @instance.reload
1219
+ @instance.bars.first.name.should == '1'
1220
+ end
1221
+
1222
+ should "return self" do
1223
+ @instance.reload.object_id.should == @instance.object_id
1188
1224
  end
1189
1225
  end
1190
1226
  end
@@ -246,20 +246,29 @@ class ValidationsTest < Test::Unit::TestCase
246
246
  doc2.should_not have_error_on(:name)
247
247
  end
248
248
 
249
- should "fail on entries that differ only in case if :case_sensitive => false" do
250
- document = Class.new do
251
- include MongoMapper::Document
252
- set_collection_name 'test'
249
+ context "with :case_sensitive => false" do
250
+ setup do
251
+ @document = Class.new do
252
+ include MongoMapper::Document
253
+ set_collection_name 'test'
253
254
 
254
- key :name
255
- validates_uniqueness_of :name, :case_sensitive => false
255
+ key :name
256
+ validates_uniqueness_of :name, :case_sensitive => false
257
+ end
256
258
  end
259
+
260
+ should "fail on entries that differ only in case" do
261
+ doc = @document.new("name" => "BLAMMO")
262
+ doc.save.should be_true
257
263
 
258
- doc = document.new("name" => "BLAMMO")
259
- doc.save.should be_true
264
+ doc2 = @document.new("name" => "blammo")
265
+ doc2.should have_error_on(:name)
266
+ end
260
267
 
261
- doc2 = document.new("name" => "blammo")
262
- doc2.should have_error_on(:name)
268
+ should "not raise an error if value is nil" do
269
+ doc = @document.new("name" => nil)
270
+ lambda { doc.valid? }.should_not raise_error
271
+ end
263
272
  end
264
273
 
265
274
  context "scoped by a single attribute" do
@@ -132,9 +132,9 @@ class AssociationBaseTest < Test::Unit::TestCase
132
132
  end
133
133
 
134
134
  context "proxy_class" do
135
- should "be ManyProxy for many" do
135
+ should "be ManyDocumentsProxy for many" do
136
136
  base = Base.new(:many, :statuses)
137
- base.proxy_class.should == ManyProxy
137
+ base.proxy_class.should == ManyDocumentsProxy
138
138
  end
139
139
 
140
140
  should "be ManyPolymorphicProxy for polymorphic many" do
@@ -0,0 +1,91 @@
1
+ require 'test_helper'
2
+
3
+ class FakeNilProxy < MongoMapper::Associations::Proxy
4
+ def find_target; nil end
5
+ end
6
+
7
+ class FakeBlankProxy < MongoMapper::Associations::Proxy
8
+ def find_target; '' end
9
+ end
10
+
11
+ class FakeProxy < MongoMapper::Associations::Proxy
12
+ def find_target
13
+ [1, 2]
14
+ end
15
+ end
16
+
17
+ class ProxyTest < Test::Unit::TestCase
18
+ def setup
19
+ @owner = mock('owner')
20
+ @owner.stubs(:new?).returns(false)
21
+ @association = mock('association')
22
+ @association.stubs(:options).returns({:extend => []})
23
+
24
+ @proxy = FakeProxy.new(@owner, @association)
25
+ @nil_proxy = FakeNilProxy.new(@owner, @association)
26
+ @blank_proxy = FakeBlankProxy.new(@owner, @association)
27
+ end
28
+
29
+ should 'return true for === target' do
30
+ @proxy = FakeProxy.new(@owner, @association)
31
+ @proxy.should === Array
32
+ end
33
+
34
+ should "set target to nil when reset is called" do
35
+ @proxy.reset
36
+ @proxy.target.should be_nil
37
+ end
38
+
39
+ should "be able to inspect the proxy" do
40
+ @proxy.inspect.should == '[1, 2]'
41
+ end
42
+
43
+ context "nil?" do
44
+ should "be true if nil" do
45
+ @nil_proxy.nil?.should be_true
46
+ end
47
+
48
+ should "be false if not nil" do
49
+ @proxy.nil?.should be_false
50
+ end
51
+ end
52
+
53
+ context "blank?" do
54
+ should "be true if blank" do
55
+ @blank_proxy.blank?.should be_true
56
+ end
57
+
58
+ should "be false if not blank" do
59
+ @proxy.blank?.should be_false
60
+ end
61
+ end
62
+
63
+ should "delegate respond_to? to target" do
64
+ @proxy.respond_to?(:each).should be_true
65
+ @proxy.respond_to?(:size).should be_true
66
+ @proxy.respond_to?(:gsub).should be_false
67
+ end
68
+
69
+ should "alias proxy owner to owner" do
70
+ @proxy.proxy_owner.should == @owner
71
+ end
72
+
73
+ should "alias proxy target to target" do
74
+ @proxy.proxy_target.should == @target
75
+ end
76
+
77
+ context "send" do
78
+ should "work if proxy responds to method" do
79
+ @proxy.send(:reset)
80
+ @proxy.target.should be_nil
81
+ end
82
+
83
+ should "work if the target responds to the method" do
84
+ @proxy.send(:size).should == 2
85
+ end
86
+
87
+ should "not work if neither the proxy or target respond to method" do
88
+ lambda { @proxy.send(:gsub) }.should raise_error
89
+ end
90
+ end
91
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongo_mapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.6
4
+ version: 0.6.7
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: 2009-12-05 00:00:00 -05:00
12
+ date: 2009-12-13 00:00:00 -05:00
13
13
  default_executable: mmconsole
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -103,12 +103,12 @@ files:
103
103
  - lib/mongo_mapper/associations/base.rb
104
104
  - lib/mongo_mapper/associations/belongs_to_polymorphic_proxy.rb
105
105
  - lib/mongo_mapper/associations/belongs_to_proxy.rb
106
+ - lib/mongo_mapper/associations/collection.rb
106
107
  - lib/mongo_mapper/associations/many_documents_as_proxy.rb
107
108
  - lib/mongo_mapper/associations/many_documents_proxy.rb
108
109
  - lib/mongo_mapper/associations/many_embedded_polymorphic_proxy.rb
109
110
  - lib/mongo_mapper/associations/many_embedded_proxy.rb
110
111
  - lib/mongo_mapper/associations/many_polymorphic_proxy.rb
111
- - lib/mongo_mapper/associations/many_proxy.rb
112
112
  - lib/mongo_mapper/associations/proxy.rb
113
113
  - lib/mongo_mapper/callbacks.rb
114
114
  - lib/mongo_mapper/dirty.rb
@@ -131,10 +131,10 @@ files:
131
131
  - test/functional/associations/test_belongs_to_polymorphic_proxy.rb
132
132
  - test/functional/associations/test_belongs_to_proxy.rb
133
133
  - test/functional/associations/test_many_documents_as_proxy.rb
134
+ - test/functional/associations/test_many_documents_proxy.rb
134
135
  - test/functional/associations/test_many_embedded_polymorphic_proxy.rb
135
136
  - test/functional/associations/test_many_embedded_proxy.rb
136
137
  - test/functional/associations/test_many_polymorphic_proxy.rb
137
- - test/functional/associations/test_many_proxy.rb
138
138
  - test/functional/test_associations.rb
139
139
  - test/functional/test_binary.rb
140
140
  - test/functional/test_callbacks.rb
@@ -150,8 +150,9 @@ files:
150
150
  - test/support/custom_matchers.rb
151
151
  - test/support/timing.rb
152
152
  - test/test_helper.rb
153
+ - test/unit/associations/test_base.rb
154
+ - test/unit/associations/test_proxy.rb
153
155
  - test/unit/serializers/test_json_serializer.rb
154
- - test/unit/test_association_base.rb
155
156
  - test/unit/test_document.rb
156
157
  - test/unit/test_dynamic_finder.rb
157
158
  - test/unit/test_embedded_document.rb
@@ -197,10 +198,10 @@ test_files:
197
198
  - test/functional/associations/test_belongs_to_polymorphic_proxy.rb
198
199
  - test/functional/associations/test_belongs_to_proxy.rb
199
200
  - test/functional/associations/test_many_documents_as_proxy.rb
201
+ - test/functional/associations/test_many_documents_proxy.rb
200
202
  - test/functional/associations/test_many_embedded_polymorphic_proxy.rb
201
203
  - test/functional/associations/test_many_embedded_proxy.rb
202
204
  - test/functional/associations/test_many_polymorphic_proxy.rb
203
- - test/functional/associations/test_many_proxy.rb
204
205
  - test/functional/test_associations.rb
205
206
  - test/functional/test_binary.rb
206
207
  - test/functional/test_callbacks.rb
@@ -216,8 +217,9 @@ test_files:
216
217
  - test/support/custom_matchers.rb
217
218
  - test/support/timing.rb
218
219
  - test/test_helper.rb
220
+ - test/unit/associations/test_base.rb
221
+ - test/unit/associations/test_proxy.rb
219
222
  - test/unit/serializers/test_json_serializer.rb
220
- - test/unit/test_association_base.rb
221
223
  - test/unit/test_document.rb
222
224
  - test/unit/test_dynamic_finder.rb
223
225
  - test/unit/test_embedded_document.rb
@@ -1,6 +0,0 @@
1
- module MongoMapper
2
- module Associations
3
- class ManyProxy < ManyDocumentsProxy
4
- end
5
- end
6
- end