mongo_mapper-unstable 2009.10.16 → 2009.10.31
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -1
- data/README.rdoc +3 -0
- data/Rakefile +31 -65
- data/VERSION +1 -1
- data/lib/mongo_mapper/associations/base.rb +31 -4
- data/lib/mongo_mapper/associations/many_documents_as_proxy.rb +0 -2
- data/lib/mongo_mapper/associations/many_documents_proxy.rb +21 -15
- data/lib/mongo_mapper/associations/many_embedded_polymorphic_proxy.rb +2 -2
- data/lib/mongo_mapper/associations/many_embedded_proxy.rb +21 -36
- data/lib/mongo_mapper/associations/many_polymorphic_proxy.rb +1 -1
- data/lib/mongo_mapper/associations/proxy.rb +1 -0
- data/lib/mongo_mapper/associations.rb +114 -17
- data/lib/mongo_mapper/callbacks.rb +18 -0
- data/lib/mongo_mapper/document.rb +230 -95
- data/lib/mongo_mapper/dynamic_finder.rb +1 -1
- data/lib/mongo_mapper/embedded_document.rb +7 -3
- data/lib/mongo_mapper/finder_options.rb +88 -56
- data/lib/mongo_mapper/pagination.rb +2 -0
- data/lib/mongo_mapper/serialization.rb +2 -3
- data/lib/mongo_mapper/serializers/json_serializer.rb +1 -1
- data/lib/mongo_mapper/support.rb +9 -0
- data/lib/mongo_mapper/validations.rb +14 -42
- data/lib/mongo_mapper.rb +15 -13
- data/mongo_mapper.gemspec +13 -13
- data/specs.watchr +2 -2
- data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +5 -5
- data/test/functional/associations/test_belongs_to_proxy.rb +28 -30
- data/test/functional/associations/test_many_documents_as_proxy.rb +4 -4
- data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +27 -3
- data/test/functional/associations/test_many_embedded_proxy.rb +58 -38
- data/test/functional/associations/test_many_polymorphic_proxy.rb +49 -7
- data/test/functional/associations/test_many_proxy.rb +65 -15
- data/test/functional/test_associations.rb +3 -3
- data/test/functional/test_binary.rb +1 -1
- data/test/functional/test_callbacks.rb +1 -1
- data/test/functional/test_dirty.rb +3 -3
- data/test/functional/test_document.rb +178 -57
- data/test/functional/test_embedded_document.rb +1 -1
- data/test/functional/test_pagination.rb +18 -18
- data/test/functional/test_rails_compatibility.rb +1 -1
- data/test/functional/test_validations.rb +80 -27
- data/test/models.rb +93 -17
- data/test/support/{test_timing.rb → timing.rb} +1 -1
- data/test/test_helper.rb +8 -11
- data/test/unit/test_association_base.rb +23 -1
- data/test/unit/test_document.rb +29 -12
- data/test/unit/test_embedded_document.rb +13 -4
- data/test/unit/test_finder_options.rb +74 -58
- data/test/unit/test_mongomapper.rb +2 -2
- data/test/unit/test_pagination.rb +4 -0
- metadata +7 -7
@@ -1,55 +1,35 @@
|
|
1
1
|
module MongoMapper
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
{'$in' => value}
|
16
|
-
end
|
17
|
-
when Hash
|
18
|
-
criteria[field] = to_mongo_criteria(value, field)
|
19
|
-
else
|
20
|
-
criteria[field] = value
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
criteria
|
25
|
-
end
|
26
|
-
|
27
|
-
def self.to_mongo_options(options)
|
28
|
-
options = options.dup
|
29
|
-
{
|
30
|
-
:fields => to_mongo_fields(options.delete(:fields) || options.delete(:select)),
|
31
|
-
:skip => (options.delete(:skip) || options.delete(:offset) || 0).to_i,
|
32
|
-
:limit => (options.delete(:limit) || 0).to_i,
|
33
|
-
:sort => options.delete(:sort) || to_mongo_sort(options.delete(:order))
|
34
|
-
}
|
2
|
+
# Controls the parsing and handling of options used by finders.
|
3
|
+
#
|
4
|
+
# == Important Note
|
5
|
+
#
|
6
|
+
# This class is private to MongoMapper and should not be considered part of
|
7
|
+
# MongoMapper's public API. Some documentation herein, however, may prove
|
8
|
+
# useful for understanding how MongoMapper handles the parsing of finder
|
9
|
+
# conditions and options.
|
10
|
+
#
|
11
|
+
# @private
|
12
|
+
class FinderOperator
|
13
|
+
def initialize(field, operator)
|
14
|
+
@field, @operator = field, operator
|
35
15
|
end
|
36
16
|
|
37
|
-
def
|
38
|
-
|
39
|
-
:_id
|
40
|
-
else
|
41
|
-
field
|
42
|
-
end
|
17
|
+
def to_criteria(value)
|
18
|
+
{@field => {@operator => value}}
|
43
19
|
end
|
44
|
-
|
20
|
+
end
|
21
|
+
|
22
|
+
class FinderOptions
|
45
23
|
OptionKeys = [:fields, :select, :skip, :offset, :limit, :sort, :order]
|
46
|
-
|
47
|
-
def initialize(options)
|
48
|
-
raise ArgumentError, "
|
49
|
-
|
50
|
-
options = options.symbolize_keys
|
51
|
-
@options, @conditions = {}, options.delete(:conditions) || {}
|
24
|
+
|
25
|
+
def initialize(model, options)
|
26
|
+
raise ArgumentError, "Options must be a hash" unless options.is_a?(Hash)
|
27
|
+
options.symbolize_keys!
|
52
28
|
|
29
|
+
@model = model
|
30
|
+
@options = {}
|
31
|
+
@conditions = options.delete(:conditions) || {}
|
32
|
+
|
53
33
|
options.each_pair do |key, value|
|
54
34
|
if OptionKeys.include?(key)
|
55
35
|
@options[key] = value
|
@@ -57,42 +37,94 @@ module MongoMapper
|
|
57
37
|
@conditions[key] = value
|
58
38
|
end
|
59
39
|
end
|
40
|
+
|
41
|
+
add_sci_scope
|
60
42
|
end
|
61
43
|
|
44
|
+
# @return [Hash] Mongo compatible criteria options
|
45
|
+
#
|
46
|
+
# @see FinderOptions#to_mongo_criteria
|
62
47
|
def criteria
|
63
|
-
|
48
|
+
to_mongo_criteria(@conditions)
|
64
49
|
end
|
65
50
|
|
51
|
+
# @return [Hash] Mongo compatible options
|
66
52
|
def options
|
67
|
-
|
53
|
+
options = @options.dup
|
54
|
+
|
55
|
+
fields = options.delete(:fields) || options.delete(:select)
|
56
|
+
skip = options.delete(:skip) || options.delete(:offset) || 0
|
57
|
+
limit = options.delete(:limit) || 0
|
58
|
+
sort = options.delete(:sort) || convert_order_to_sort(options.delete(:order))
|
59
|
+
|
60
|
+
{:fields => to_mongo_fields(fields), :skip => skip.to_i, :limit => limit.to_i, :sort => sort}
|
68
61
|
end
|
69
62
|
|
63
|
+
# @return [Array<Hash>] Mongo criteria and options enclosed in an Array
|
70
64
|
def to_a
|
71
65
|
[criteria, options]
|
72
66
|
end
|
73
|
-
|
67
|
+
|
74
68
|
private
|
75
|
-
def
|
69
|
+
def to_mongo_criteria(conditions, parent_key=nil)
|
70
|
+
criteria = {}
|
71
|
+
|
72
|
+
conditions.each_pair do |field, value|
|
73
|
+
field = normalized_field(field)
|
74
|
+
if field.is_a?(FinderOperator)
|
75
|
+
criteria.merge!(field.to_criteria(value))
|
76
|
+
next
|
77
|
+
end
|
78
|
+
case value
|
79
|
+
when Array
|
80
|
+
operator_present = field.to_s =~ /^\$/
|
81
|
+
criteria[field] = operator?(field) ? value : {'$in' => value}
|
82
|
+
when Hash
|
83
|
+
criteria[field] = to_mongo_criteria(value, field)
|
84
|
+
else
|
85
|
+
criteria[field] = value
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
criteria
|
90
|
+
end
|
91
|
+
|
92
|
+
def operator?(field)
|
93
|
+
field.to_s =~ /^\$/
|
94
|
+
end
|
95
|
+
|
96
|
+
def normalized_field(field)
|
97
|
+
field.to_s == 'id' ? :_id : field
|
98
|
+
end
|
99
|
+
|
100
|
+
# adds _type single collection inheritance scope for models that need it
|
101
|
+
def add_sci_scope
|
102
|
+
if @model.single_collection_inherited?
|
103
|
+
@conditions[:_type] = @model.to_s
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def to_mongo_fields(fields)
|
76
108
|
return if fields.blank?
|
77
|
-
|
109
|
+
|
78
110
|
if fields.is_a?(String)
|
79
111
|
fields.split(',').map { |field| field.strip }
|
80
112
|
else
|
81
113
|
fields.flatten.compact
|
82
114
|
end
|
83
115
|
end
|
84
|
-
|
85
|
-
def
|
116
|
+
|
117
|
+
def convert_order_to_sort(sort)
|
86
118
|
return if sort.blank?
|
87
119
|
pieces = sort.split(',')
|
88
120
|
pieces.map { |s| to_mongo_sort_piece(s) }
|
89
121
|
end
|
90
|
-
|
91
|
-
def
|
122
|
+
|
123
|
+
def to_mongo_sort_piece(str)
|
92
124
|
field, direction = str.strip.split(' ')
|
93
125
|
direction ||= 'ASC'
|
94
126
|
direction = direction.upcase == 'ASC' ? 1 : -1
|
95
127
|
[field, direction]
|
96
128
|
end
|
97
129
|
end
|
98
|
-
end
|
130
|
+
end
|
@@ -5,7 +5,7 @@ module MongoMapper #:nodoc:
|
|
5
5
|
class Serializer #:nodoc:
|
6
6
|
attr_reader :options
|
7
7
|
|
8
|
-
def initialize(record, options
|
8
|
+
def initialize(record, options={})
|
9
9
|
@record, @options = record, options.dup
|
10
10
|
end
|
11
11
|
|
@@ -51,5 +51,4 @@ module MongoMapper #:nodoc:
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
-
|
55
|
-
require dir + 'json_serializer'
|
54
|
+
require 'mongo_mapper/serializers/json_serializer'
|
@@ -49,7 +49,7 @@ module MongoMapper #:nodoc:
|
|
49
49
|
# # => {"id": 1, "name": "Konata Izumi", "age": 16,
|
50
50
|
# "created_at": "2006/08/01", "awesome": true,
|
51
51
|
# "permalink": "1-konata-izumi"}
|
52
|
-
def to_json(options
|
52
|
+
def to_json(options={})
|
53
53
|
apply_to_json_defaults(options)
|
54
54
|
|
55
55
|
if include_root_in_json
|
data/lib/mongo_mapper/support.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
class BasicObject #:nodoc:
|
2
|
+
alias_method :proxy_extend, :extend
|
2
3
|
instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|^methods$|instance_eval|proxy_|^object_id$)/ }
|
3
4
|
end unless defined?(BasicObject)
|
4
5
|
|
@@ -129,6 +130,14 @@ class String
|
|
129
130
|
end
|
130
131
|
end
|
131
132
|
|
133
|
+
class Symbol
|
134
|
+
%w{gt lt gte lte ne in nin mod size where exists}.each do |operator|
|
135
|
+
define_method operator do
|
136
|
+
MongoMapper::FinderOperator.new(self, "$#{operator}")
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
132
141
|
class Time
|
133
142
|
def self.to_mongo(value)
|
134
143
|
if value.nil? || value == ''
|
@@ -4,65 +4,37 @@ module MongoMapper
|
|
4
4
|
def validates_uniqueness_of(*args)
|
5
5
|
add_validations(args, MongoMapper::Validations::ValidatesUniquenessOf)
|
6
6
|
end
|
7
|
-
|
8
|
-
def validates_exclusion_of(*args)
|
9
|
-
add_validations(args, MongoMapper::Validations::ValidatesExclusionOf)
|
10
|
-
end
|
11
|
-
|
12
|
-
def validates_inclusion_of(*args)
|
13
|
-
add_validations(args, MongoMapper::Validations::ValidatesInclusionOf)
|
14
|
-
end
|
15
7
|
end
|
16
8
|
|
17
9
|
class ValidatesUniquenessOf < Validatable::ValidationBase
|
18
|
-
option :scope
|
19
|
-
|
10
|
+
option :scope, :case_sensitive
|
11
|
+
default :case_sensitive => true
|
12
|
+
|
20
13
|
def valid?(instance)
|
21
|
-
|
14
|
+
value = instance[attribute]
|
15
|
+
return true if allow_blank && value.blank?
|
16
|
+
base_conditions = case_sensitive ? {self.attribute => value} : {}
|
17
|
+
doc = instance.class.first(base_conditions.merge(scope_conditions(instance)).merge(where_conditions(instance)))
|
22
18
|
doc.nil? || instance.id == doc.id
|
23
19
|
end
|
24
20
|
|
25
21
|
def message(instance)
|
26
22
|
super || "has already been taken"
|
27
23
|
end
|
28
|
-
|
24
|
+
|
29
25
|
def scope_conditions(instance)
|
30
26
|
return {} unless scope
|
31
27
|
Array(scope).inject({}) do |conditions, key|
|
32
28
|
conditions.merge(key => instance[key])
|
33
29
|
end
|
34
30
|
end
|
35
|
-
end
|
36
|
-
|
37
|
-
class ValidatesExclusionOf < Validatable::ValidationBase
|
38
|
-
required_option :within
|
39
|
-
|
40
|
-
def valid?(instance)
|
41
|
-
value = instance[attribute]
|
42
|
-
return true if allow_nil && value.nil?
|
43
|
-
return true if allow_blank && value.blank?
|
44
|
-
|
45
|
-
!within.include?(instance[attribute])
|
46
|
-
end
|
47
|
-
|
48
|
-
def message(instance)
|
49
|
-
super || "is reserved"
|
50
|
-
end
|
51
|
-
end
|
52
31
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
return true if allow_blank && value.blank?
|
60
|
-
|
61
|
-
within.include?(value)
|
62
|
-
end
|
63
|
-
|
64
|
-
def message(instance)
|
65
|
-
super || "is not in the list"
|
32
|
+
def where_conditions(instance)
|
33
|
+
conditions = {}
|
34
|
+
unless case_sensitive
|
35
|
+
conditions.merge!({'$where' => "this.#{attribute}.toLowerCase() == '#{instance[attribute].downcase}'"})
|
36
|
+
end
|
37
|
+
conditions
|
66
38
|
end
|
67
39
|
end
|
68
40
|
end
|
data/lib/mongo_mapper.rb
CHANGED
@@ -1,16 +1,19 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
gem 'activesupport', '>= 2.3'
|
4
|
-
gem 'mongo', '0.15.1'
|
5
|
-
gem 'jnunemaker-validatable', '1.7.4'
|
6
|
-
|
7
|
-
require 'activesupport'
|
1
|
+
require 'active_support'
|
8
2
|
require 'mongo'
|
9
3
|
require 'validatable'
|
10
4
|
|
11
5
|
module MongoMapper
|
12
|
-
|
13
|
-
|
6
|
+
# generic MM error
|
7
|
+
class MongoMapperError < StandardError; end
|
8
|
+
|
9
|
+
# raised when key expected to exist but not found
|
10
|
+
class KeyNotFound < MongoMapperError; end
|
11
|
+
|
12
|
+
# raised when document expected but not found
|
13
|
+
class DocumentNotFound < MongoMapperError; end
|
14
|
+
|
15
|
+
# raised when document not valid and using !
|
16
|
+
class DocumentNotValid < MongoMapperError
|
14
17
|
def initialize(document)
|
15
18
|
@document = document
|
16
19
|
super("Validation failed: #{@document.errors.full_messages.join(", ")}")
|
@@ -60,13 +63,12 @@ module MongoMapper
|
|
60
63
|
module Finders
|
61
64
|
def dynamic_find(finder, args)
|
62
65
|
attributes = {}
|
63
|
-
find_options = args.extract_options!.deep_merge(:conditions => attributes)
|
64
|
-
|
65
66
|
finder.attributes.each_with_index do |attr, index|
|
66
67
|
attributes[attr] = args[index]
|
67
68
|
end
|
68
|
-
|
69
|
-
|
69
|
+
|
70
|
+
options = args.extract_options!.merge(attributes)
|
71
|
+
result = find(finder.finder, options)
|
70
72
|
|
71
73
|
if result.nil?
|
72
74
|
if finder.bang
|
data/mongo_mapper.gemspec
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{mongo_mapper}
|
8
|
-
s.version = "0.5.
|
8
|
+
s.version = "0.5.8"
|
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-10-
|
12
|
+
s.date = %q{2009-10-29}
|
13
13
|
s.default_executable = %q{mmconsole}
|
14
14
|
s.email = %q{nunemaker@gmail.com}
|
15
15
|
s.executables = ["mmconsole"]
|
@@ -73,7 +73,7 @@ Gem::Specification.new do |s|
|
|
73
73
|
"test/functional/test_validations.rb",
|
74
74
|
"test/models.rb",
|
75
75
|
"test/support/custom_matchers.rb",
|
76
|
-
"test/support/
|
76
|
+
"test/support/timing.rb",
|
77
77
|
"test/test_helper.rb",
|
78
78
|
"test/unit/serializers/test_json_serializer.rb",
|
79
79
|
"test/unit/test_association_base.rb",
|
@@ -94,7 +94,6 @@ Gem::Specification.new do |s|
|
|
94
94
|
s.homepage = %q{http://github.com/jnunemaker/mongomapper}
|
95
95
|
s.rdoc_options = ["--charset=UTF-8"]
|
96
96
|
s.require_paths = ["lib"]
|
97
|
-
s.rubyforge_project = %q{mongomapper}
|
98
97
|
s.rubygems_version = %q{1.3.5}
|
99
98
|
s.summary = %q{Awesome gem for modeling your domain and storing it in mongo}
|
100
99
|
s.test_files = [
|
@@ -117,7 +116,7 @@ Gem::Specification.new do |s|
|
|
117
116
|
"test/functional/test_validations.rb",
|
118
117
|
"test/models.rb",
|
119
118
|
"test/support/custom_matchers.rb",
|
120
|
-
"test/support/
|
119
|
+
"test/support/timing.rb",
|
121
120
|
"test/test_helper.rb",
|
122
121
|
"test/unit/serializers/test_json_serializer.rb",
|
123
122
|
"test/unit/test_association_base.rb",
|
@@ -142,16 +141,16 @@ Gem::Specification.new do |s|
|
|
142
141
|
|
143
142
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
144
143
|
s.add_runtime_dependency(%q<activesupport>, [">= 2.3"])
|
145
|
-
s.add_runtime_dependency(%q<mongo>, ["= 0.
|
146
|
-
s.add_runtime_dependency(%q<jnunemaker-validatable>, ["= 1.
|
144
|
+
s.add_runtime_dependency(%q<mongo>, ["= 0.16"])
|
145
|
+
s.add_runtime_dependency(%q<jnunemaker-validatable>, ["= 1.8.0"])
|
147
146
|
s.add_development_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
|
148
147
|
s.add_development_dependency(%q<shoulda>, ["= 2.10.2"])
|
149
148
|
s.add_development_dependency(%q<timecop>, ["= 0.3.1"])
|
150
149
|
s.add_development_dependency(%q<mocha>, ["= 0.9.4"])
|
151
150
|
else
|
152
151
|
s.add_dependency(%q<activesupport>, [">= 2.3"])
|
153
|
-
s.add_dependency(%q<mongo>, ["= 0.
|
154
|
-
s.add_dependency(%q<jnunemaker-validatable>, ["= 1.
|
152
|
+
s.add_dependency(%q<mongo>, ["= 0.16"])
|
153
|
+
s.add_dependency(%q<jnunemaker-validatable>, ["= 1.8.0"])
|
155
154
|
s.add_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
|
156
155
|
s.add_dependency(%q<shoulda>, ["= 2.10.2"])
|
157
156
|
s.add_dependency(%q<timecop>, ["= 0.3.1"])
|
@@ -159,11 +158,12 @@ Gem::Specification.new do |s|
|
|
159
158
|
end
|
160
159
|
else
|
161
160
|
s.add_dependency(%q<activesupport>, [">= 2.3"])
|
162
|
-
s.add_dependency(%q<mongo>, ["= 0.
|
163
|
-
s.add_dependency(%q<jnunemaker-validatable>, ["= 1.
|
161
|
+
s.add_dependency(%q<mongo>, ["= 0.16"])
|
162
|
+
s.add_dependency(%q<jnunemaker-validatable>, ["= 1.8.0"])
|
164
163
|
s.add_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
|
165
164
|
s.add_dependency(%q<shoulda>, ["= 2.10.2"])
|
166
165
|
s.add_dependency(%q<timecop>, ["= 0.3.1"])
|
167
166
|
s.add_dependency(%q<mocha>, ["= 0.9.4"])
|
168
167
|
end
|
169
168
|
end
|
169
|
+
|
data/specs.watchr
CHANGED
@@ -4,7 +4,7 @@ def run(cmd)
|
|
4
4
|
end
|
5
5
|
|
6
6
|
def run_test_file(file)
|
7
|
-
run
|
7
|
+
run %Q(ruby -I"lib:test" -rubygems #{file})
|
8
8
|
end
|
9
9
|
|
10
10
|
def run_all_tests
|
@@ -12,7 +12,7 @@ def run_all_tests
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def related_test_files(path)
|
15
|
-
Dir['test/**/*.rb'].select { |file| file =~
|
15
|
+
Dir['test/**/*.rb'].select { |file| file =~ /test_#{File.basename(path)}/ }
|
16
16
|
end
|
17
17
|
|
18
18
|
watch('test/test_helper\.rb') { run_all_tests }
|
@@ -3,8 +3,8 @@ require 'models'
|
|
3
3
|
|
4
4
|
class BelongsToPolymorphicProxyTest < Test::Unit::TestCase
|
5
5
|
def setup
|
6
|
-
Status.collection.
|
7
|
-
Project.collection.
|
6
|
+
Status.collection.remove
|
7
|
+
Project.collection.remove
|
8
8
|
end
|
9
9
|
|
10
10
|
should "default to nil" do
|
@@ -14,7 +14,7 @@ class BelongsToPolymorphicProxyTest < Test::Unit::TestCase
|
|
14
14
|
end
|
15
15
|
|
16
16
|
should "be able to replace the association" do
|
17
|
-
status = Status.new
|
17
|
+
status = Status.new(:name => 'Foo!')
|
18
18
|
project = Project.new(:name => "mongomapper")
|
19
19
|
status.target = project
|
20
20
|
status.save.should be_true
|
@@ -27,7 +27,7 @@ class BelongsToPolymorphicProxyTest < Test::Unit::TestCase
|
|
27
27
|
end
|
28
28
|
|
29
29
|
should "unset the association" do
|
30
|
-
status = Status.new
|
30
|
+
status = Status.new(:name => 'Foo!')
|
31
31
|
project = Project.new(:name => "mongomapper")
|
32
32
|
status.target = project
|
33
33
|
status.save.should be_true
|
@@ -41,7 +41,7 @@ class BelongsToPolymorphicProxyTest < Test::Unit::TestCase
|
|
41
41
|
|
42
42
|
context "association id set but document not found" do
|
43
43
|
setup do
|
44
|
-
@status = Status.new
|
44
|
+
@status = Status.new(:name => 'Foo!')
|
45
45
|
project = Project.new(:name => "mongomapper")
|
46
46
|
@status.target = project
|
47
47
|
@status.save.should be_true
|
@@ -2,48 +2,46 @@ require 'test_helper'
|
|
2
2
|
require 'models'
|
3
3
|
|
4
4
|
class BelongsToProxyTest < Test::Unit::TestCase
|
5
|
-
def setup
|
6
|
-
|
7
|
-
|
5
|
+
def setup
|
6
|
+
@post_class = Class.new do
|
7
|
+
include MongoMapper::Document
|
8
|
+
end
|
9
|
+
|
10
|
+
@comment_class = Class.new do
|
11
|
+
include MongoMapper::Document
|
12
|
+
key :post_id, String
|
13
|
+
end
|
14
|
+
@comment_class.belongs_to :post, :class => @post_class
|
15
|
+
|
16
|
+
@post_class.collection.remove
|
17
|
+
@comment_class.collection.remove
|
8
18
|
end
|
9
19
|
|
10
20
|
should "default to nil" do
|
11
|
-
|
12
|
-
status.project.nil?.should == true
|
13
|
-
status.project.inspect.should == 'nil'
|
21
|
+
@comment_class.new.post.nil?.should be_true
|
14
22
|
end
|
15
23
|
|
16
24
|
should "be able to replace the association" do
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
status.save.should be_true
|
25
|
+
post = @post_class.new(:name => 'mongomapper')
|
26
|
+
comment = @comment_class.new(:name => 'Foo!', :post => post)
|
27
|
+
comment.save.should be_true
|
21
28
|
|
22
|
-
|
23
|
-
|
24
|
-
|
29
|
+
comment = comment.reload
|
30
|
+
comment.post.should == post
|
31
|
+
comment.post.nil?.should be_false
|
25
32
|
end
|
26
33
|
|
27
34
|
should "unset the association" do
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
status.save.should be_true
|
35
|
+
post = @post_class.new(:name => 'mongomapper')
|
36
|
+
comment = @comment_class.new(:name => 'Foo!', :post => post)
|
37
|
+
comment.save.should be_true
|
32
38
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
from_db.project.inspect.should == 'nil'
|
39
|
+
comment = comment.reload
|
40
|
+
comment.post = nil
|
41
|
+
comment.post.nil?.should be_true
|
37
42
|
end
|
38
43
|
|
39
|
-
|
40
|
-
|
41
|
-
@status = Status.new(:name => 'Foo', :project_id => '1234')
|
42
|
-
end
|
43
|
-
|
44
|
-
should "return nil instead of raising error" do
|
45
|
-
@status.project.nil?.should be_true
|
46
|
-
@status.project.inspect.should == 'nil'
|
47
|
-
end
|
44
|
+
should "return nil if id set but document not found" do
|
45
|
+
@comment_class.new(:name => 'Foo', :post_id => '1234').post.nil?.should be_true
|
48
46
|
end
|
49
47
|
end
|
@@ -3,8 +3,8 @@ require 'models'
|
|
3
3
|
|
4
4
|
class ManyDocumentsAsProxyTest < Test::Unit::TestCase
|
5
5
|
def setup
|
6
|
-
Post.collection.
|
7
|
-
PostComment.collection.
|
6
|
+
Post.collection.remove
|
7
|
+
PostComment.collection.remove
|
8
8
|
end
|
9
9
|
|
10
10
|
should "default reader to empty array" do
|
@@ -137,7 +137,7 @@ class ManyDocumentsAsProxyTest < Test::Unit::TestCase
|
|
137
137
|
end
|
138
138
|
|
139
139
|
should "work with conditions" do
|
140
|
-
comments = @post.comments.find(:all, :
|
140
|
+
comments = @post.comments.find(:all, :body => 'comment1')
|
141
141
|
comments.should == [@comment1]
|
142
142
|
end
|
143
143
|
|
@@ -154,7 +154,7 @@ class ManyDocumentsAsProxyTest < Test::Unit::TestCase
|
|
154
154
|
end
|
155
155
|
|
156
156
|
should "work with conditions" do
|
157
|
-
comments = @post.comments.all(:
|
157
|
+
comments = @post.comments.all(:body => 'comment1')
|
158
158
|
comments.should == [@comment1]
|
159
159
|
end
|
160
160
|
|
@@ -3,8 +3,8 @@ require 'models'
|
|
3
3
|
|
4
4
|
class ManyEmbeddedPolymorphicProxyTest < Test::Unit::TestCase
|
5
5
|
def setup
|
6
|
-
Catalog.collection.
|
7
|
-
TrModels::Fleet.collection.
|
6
|
+
Catalog.collection.remove
|
7
|
+
TrModels::Fleet.collection.remove
|
8
8
|
end
|
9
9
|
|
10
10
|
should "default reader to empty array" do
|
@@ -129,4 +129,28 @@ class ManyEmbeddedPolymorphicProxyTest < Test::Unit::TestCase
|
|
129
129
|
from_db.transports[2].icu.should == true
|
130
130
|
end
|
131
131
|
end
|
132
|
-
|
132
|
+
|
133
|
+
context "extending the association" do
|
134
|
+
should "work using a block passed to many" do
|
135
|
+
catalog = Catalog.new
|
136
|
+
medias = catalog.medias = [
|
137
|
+
Video.new("file" => "video.mpg", "length" => 3600, :visible => true),
|
138
|
+
Music.new("file" => "music.mp3", "bitrate" => "128kbps", :visible => true),
|
139
|
+
Image.new("file" => "image.png", "width" => 800, "height" => 600, :visible => false)
|
140
|
+
]
|
141
|
+
catalog.save
|
142
|
+
catalog.medias.visible.should == [medias[0], medias[1]]
|
143
|
+
end
|
144
|
+
|
145
|
+
should "work using many's :extend option" do
|
146
|
+
fleet = TrModels::Fleet.new
|
147
|
+
transports = fleet.transports = [
|
148
|
+
TrModels::Car.new("license_plate" => "ABC1223", "model" => "Honda Civic", "year" => 2003, :purchased_on => 2.years.ago.to_date),
|
149
|
+
TrModels::Bus.new("license_plate" => "XYZ9090", "max_passengers" => 51, :purchased_on => 3.years.ago.to_date),
|
150
|
+
TrModels::Ambulance.new("license_plate" => "HDD3030", "icu" => true, :purchased_on => 1.year.ago.to_date)
|
151
|
+
]
|
152
|
+
fleet.save
|
153
|
+
fleet.transports.to_be_replaced.should == [transports[1]]
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|