mongo_mapper-unstable 2009.10.16 → 2009.10.31
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/.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
|