mongoid-locomotive 2.0.0.beta9
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/MIT_LICENSE +20 -0
- data/README.rdoc +47 -0
- data/lib/mongoid.rb +141 -0
- data/lib/mongoid/associations.rb +306 -0
- data/lib/mongoid/associations/embedded_in.rb +74 -0
- data/lib/mongoid/associations/embeds_many.rb +280 -0
- data/lib/mongoid/associations/embeds_one.rb +97 -0
- data/lib/mongoid/associations/foreign_key.rb +35 -0
- data/lib/mongoid/associations/meta_data.rb +38 -0
- data/lib/mongoid/associations/options.rb +62 -0
- data/lib/mongoid/associations/proxy.rb +33 -0
- data/lib/mongoid/associations/referenced_in.rb +59 -0
- data/lib/mongoid/associations/references_many.rb +245 -0
- data/lib/mongoid/associations/references_many_as_array.rb +78 -0
- data/lib/mongoid/associations/references_one.rb +99 -0
- data/lib/mongoid/atomicity.rb +55 -0
- data/lib/mongoid/attributes.rb +242 -0
- data/lib/mongoid/callbacks.rb +21 -0
- data/lib/mongoid/collection.rb +120 -0
- data/lib/mongoid/collections.rb +71 -0
- data/lib/mongoid/collections/cyclic_iterator.rb +34 -0
- data/lib/mongoid/collections/master.rb +29 -0
- data/lib/mongoid/collections/operations.rb +41 -0
- data/lib/mongoid/collections/slaves.rb +45 -0
- data/lib/mongoid/components.rb +34 -0
- data/lib/mongoid/config.rb +263 -0
- data/lib/mongoid/contexts.rb +24 -0
- data/lib/mongoid/contexts/enumerable.rb +156 -0
- data/lib/mongoid/contexts/ids.rb +25 -0
- data/lib/mongoid/contexts/mongo.rb +285 -0
- data/lib/mongoid/contexts/paging.rb +50 -0
- data/lib/mongoid/criteria.rb +248 -0
- data/lib/mongoid/criterion/complex.rb +21 -0
- data/lib/mongoid/criterion/exclusion.rb +65 -0
- data/lib/mongoid/criterion/inclusion.rb +110 -0
- data/lib/mongoid/criterion/optional.rb +189 -0
- data/lib/mongoid/cursor.rb +81 -0
- data/lib/mongoid/deprecation.rb +21 -0
- data/lib/mongoid/dirty.rb +252 -0
- data/lib/mongoid/document.rb +210 -0
- data/lib/mongoid/errors.rb +131 -0
- data/lib/mongoid/extensions.rb +115 -0
- data/lib/mongoid/extensions/array/accessors.rb +17 -0
- data/lib/mongoid/extensions/array/assimilation.rb +26 -0
- data/lib/mongoid/extensions/array/conversions.rb +23 -0
- data/lib/mongoid/extensions/array/parentization.rb +13 -0
- data/lib/mongoid/extensions/big_decimal/conversions.rb +19 -0
- data/lib/mongoid/extensions/binary/conversions.rb +17 -0
- data/lib/mongoid/extensions/boolean/conversions.rb +27 -0
- data/lib/mongoid/extensions/date/conversions.rb +24 -0
- data/lib/mongoid/extensions/datetime/conversions.rb +12 -0
- data/lib/mongoid/extensions/false_class/equality.rb +13 -0
- data/lib/mongoid/extensions/float/conversions.rb +20 -0
- data/lib/mongoid/extensions/hash/accessors.rb +42 -0
- data/lib/mongoid/extensions/hash/assimilation.rb +40 -0
- data/lib/mongoid/extensions/hash/conversions.rb +42 -0
- data/lib/mongoid/extensions/hash/criteria_helpers.rb +20 -0
- data/lib/mongoid/extensions/hash/scoping.rb +12 -0
- data/lib/mongoid/extensions/integer/conversions.rb +20 -0
- data/lib/mongoid/extensions/nil/assimilation.rb +17 -0
- data/lib/mongoid/extensions/object/conversions.rb +21 -0
- data/lib/mongoid/extensions/objectid/conversions.rb +15 -0
- data/lib/mongoid/extensions/proc/scoping.rb +12 -0
- data/lib/mongoid/extensions/set/conversions.rb +20 -0
- data/lib/mongoid/extensions/string/conversions.rb +15 -0
- data/lib/mongoid/extensions/string/inflections.rb +97 -0
- data/lib/mongoid/extensions/symbol/inflections.rb +40 -0
- data/lib/mongoid/extensions/time_conversions.rb +35 -0
- data/lib/mongoid/extensions/true_class/equality.rb +13 -0
- data/lib/mongoid/extras.rb +61 -0
- data/lib/mongoid/factory.rb +20 -0
- data/lib/mongoid/field.rb +83 -0
- data/lib/mongoid/fields.rb +62 -0
- data/lib/mongoid/finders.rb +145 -0
- data/lib/mongoid/hierarchy.rb +74 -0
- data/lib/mongoid/identity.rb +47 -0
- data/lib/mongoid/indexes.rb +27 -0
- data/lib/mongoid/javascript.rb +21 -0
- data/lib/mongoid/javascript/functions.yml +37 -0
- data/lib/mongoid/logger.rb +19 -0
- data/lib/mongoid/matchers.rb +35 -0
- data/lib/mongoid/matchers/all.rb +11 -0
- data/lib/mongoid/matchers/default.rb +26 -0
- data/lib/mongoid/matchers/exists.rb +13 -0
- data/lib/mongoid/matchers/gt.rb +11 -0
- data/lib/mongoid/matchers/gte.rb +11 -0
- data/lib/mongoid/matchers/in.rb +11 -0
- data/lib/mongoid/matchers/lt.rb +11 -0
- data/lib/mongoid/matchers/lte.rb +11 -0
- data/lib/mongoid/matchers/ne.rb +11 -0
- data/lib/mongoid/matchers/nin.rb +11 -0
- data/lib/mongoid/matchers/size.rb +11 -0
- data/lib/mongoid/memoization.rb +33 -0
- data/lib/mongoid/named_scope.rb +37 -0
- data/lib/mongoid/paranoia.rb +106 -0
- data/lib/mongoid/paths.rb +61 -0
- data/lib/mongoid/persistence.rb +216 -0
- data/lib/mongoid/persistence/command.rb +39 -0
- data/lib/mongoid/persistence/insert.rb +48 -0
- data/lib/mongoid/persistence/insert_embedded.rb +44 -0
- data/lib/mongoid/persistence/remove.rb +39 -0
- data/lib/mongoid/persistence/remove_all.rb +38 -0
- data/lib/mongoid/persistence/remove_embedded.rb +50 -0
- data/lib/mongoid/persistence/update.rb +71 -0
- data/lib/mongoid/railtie.rb +67 -0
- data/lib/mongoid/railties/database.rake +60 -0
- data/lib/mongoid/scope.rb +75 -0
- data/lib/mongoid/state.rb +32 -0
- data/lib/mongoid/timestamps.rb +27 -0
- data/lib/mongoid/validations.rb +51 -0
- data/lib/mongoid/validations/associated.rb +32 -0
- data/lib/mongoid/validations/locale/en.yml +5 -0
- data/lib/mongoid/validations/uniqueness.rb +56 -0
- data/lib/mongoid/version.rb +4 -0
- data/lib/mongoid/versioning.rb +26 -0
- data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +24 -0
- data/lib/rails/generators/mongoid/model/model_generator.rb +24 -0
- data/lib/rails/generators/mongoid/model/templates/model.rb +15 -0
- data/lib/rails/generators/mongoid_generator.rb +61 -0
- data/spec/integration/mongoid/association_attributes_spec.rb +71 -0
- data/spec/integration/mongoid/associations_spec.rb +768 -0
- data/spec/integration/mongoid/attributes_spec.rb +59 -0
- data/spec/integration/mongoid/callback_spec.rb +33 -0
- data/spec/integration/mongoid/contexts/enumerable_spec.rb +33 -0
- data/spec/integration/mongoid/criteria_spec.rb +281 -0
- data/spec/integration/mongoid/dirty_spec.rb +85 -0
- data/spec/integration/mongoid/document_spec.rb +741 -0
- data/spec/integration/mongoid/extensions_spec.rb +22 -0
- data/spec/integration/mongoid/finders_spec.rb +119 -0
- data/spec/integration/mongoid/inheritance_spec.rb +171 -0
- data/spec/integration/mongoid/named_scope_spec.rb +58 -0
- data/spec/integration/mongoid/paranoia_spec.rb +44 -0
- data/spec/integration/mongoid/persistence/update_spec.rb +46 -0
- data/spec/integration/mongoid/persistence_spec.rb +311 -0
- data/spec/integration/mongoid/validations/uniqueness_spec.rb +206 -0
- data/spec/models/account.rb +5 -0
- data/spec/models/address.rb +40 -0
- data/spec/models/agent.rb +7 -0
- data/spec/models/animal.rb +15 -0
- data/spec/models/answer.rb +4 -0
- data/spec/models/callbacks.rb +47 -0
- data/spec/models/category.rb +13 -0
- data/spec/models/comment.rb +10 -0
- data/spec/models/country_code.rb +6 -0
- data/spec/models/employer.rb +5 -0
- data/spec/models/favorite.rb +8 -0
- data/spec/models/game.rb +9 -0
- data/spec/models/inheritance.rb +72 -0
- data/spec/models/location.rb +5 -0
- data/spec/models/login.rb +6 -0
- data/spec/models/mixed_drink.rb +4 -0
- data/spec/models/name.rb +13 -0
- data/spec/models/namespacing.rb +11 -0
- data/spec/models/paranoid_post.rb +18 -0
- data/spec/models/parents.rb +32 -0
- data/spec/models/patient.rb +15 -0
- data/spec/models/person.rb +106 -0
- data/spec/models/pet.rb +7 -0
- data/spec/models/pet_owner.rb +6 -0
- data/spec/models/phone.rb +7 -0
- data/spec/models/post.rb +25 -0
- data/spec/models/preference.rb +7 -0
- data/spec/models/question.rb +8 -0
- data/spec/models/survey.rb +6 -0
- data/spec/models/translation.rb +5 -0
- data/spec/models/user.rb +6 -0
- data/spec/models/user_accout.rb +5 -0
- data/spec/models/vet_visit.rb +5 -0
- data/spec/models/video.rb +5 -0
- data/spec/spec_helper.rb +33 -0
- data/spec/unit/mongoid/associations/embedded_in_spec.rb +193 -0
- data/spec/unit/mongoid/associations/embeds_many_spec.rb +626 -0
- data/spec/unit/mongoid/associations/embeds_one_spec.rb +287 -0
- data/spec/unit/mongoid/associations/foreign_key_spec.rb +90 -0
- data/spec/unit/mongoid/associations/meta_data_spec.rb +110 -0
- data/spec/unit/mongoid/associations/options_spec.rb +215 -0
- data/spec/unit/mongoid/associations/referenced_in_spec.rb +145 -0
- data/spec/unit/mongoid/associations/references_many_as_array_spec.rb +424 -0
- data/spec/unit/mongoid/associations/references_many_spec.rb +502 -0
- data/spec/unit/mongoid/associations/references_one_spec.rb +204 -0
- data/spec/unit/mongoid/associations_spec.rb +688 -0
- data/spec/unit/mongoid/atomicity_spec.rb +164 -0
- data/spec/unit/mongoid/attributes_spec.rb +646 -0
- data/spec/unit/mongoid/callbacks_spec.rb +85 -0
- data/spec/unit/mongoid/collection_spec.rb +187 -0
- data/spec/unit/mongoid/collections/cyclic_iterator_spec.rb +75 -0
- data/spec/unit/mongoid/collections/master_spec.rb +41 -0
- data/spec/unit/mongoid/collections/slaves_spec.rb +81 -0
- data/spec/unit/mongoid/collections_spec.rb +98 -0
- data/spec/unit/mongoid/config_spec.rb +298 -0
- data/spec/unit/mongoid/contexts/enumerable_spec.rb +447 -0
- data/spec/unit/mongoid/contexts/mongo_spec.rb +703 -0
- data/spec/unit/mongoid/contexts_spec.rb +25 -0
- data/spec/unit/mongoid/criteria_spec.rb +873 -0
- data/spec/unit/mongoid/criterion/complex_spec.rb +17 -0
- data/spec/unit/mongoid/criterion/exclusion_spec.rb +121 -0
- data/spec/unit/mongoid/criterion/inclusion_spec.rb +274 -0
- data/spec/unit/mongoid/criterion/optional_spec.rb +483 -0
- data/spec/unit/mongoid/cursor_spec.rb +80 -0
- data/spec/unit/mongoid/deprecation_spec.rb +24 -0
- data/spec/unit/mongoid/dirty_spec.rb +430 -0
- data/spec/unit/mongoid/document_spec.rb +623 -0
- data/spec/unit/mongoid/errors_spec.rb +154 -0
- data/spec/unit/mongoid/extensions/array/accessors_spec.rb +50 -0
- data/spec/unit/mongoid/extensions/array/assimilation_spec.rb +24 -0
- data/spec/unit/mongoid/extensions/array/conversions_spec.rb +52 -0
- data/spec/unit/mongoid/extensions/array/parentization_spec.rb +20 -0
- data/spec/unit/mongoid/extensions/big_decimal/conversions_spec.rb +36 -0
- data/spec/unit/mongoid/extensions/binary/conversions_spec.rb +22 -0
- data/spec/unit/mongoid/extensions/boolean/conversions_spec.rb +49 -0
- data/spec/unit/mongoid/extensions/date/conversions_spec.rb +145 -0
- data/spec/unit/mongoid/extensions/datetime/conversions_spec.rb +14 -0
- data/spec/unit/mongoid/extensions/false_class/equality_spec.rb +35 -0
- data/spec/unit/mongoid/extensions/float/conversions_spec.rb +61 -0
- data/spec/unit/mongoid/extensions/hash/accessors_spec.rb +184 -0
- data/spec/unit/mongoid/extensions/hash/assimilation_spec.rb +59 -0
- data/spec/unit/mongoid/extensions/hash/conversions_spec.rb +35 -0
- data/spec/unit/mongoid/extensions/hash/criteria_helpers_spec.rb +17 -0
- data/spec/unit/mongoid/extensions/hash/scoping_spec.rb +14 -0
- data/spec/unit/mongoid/extensions/integer/conversions_spec.rb +61 -0
- data/spec/unit/mongoid/extensions/nil/assimilation_spec.rb +29 -0
- data/spec/unit/mongoid/extensions/object/conversions_spec.rb +44 -0
- data/spec/unit/mongoid/extensions/objectid/conversions_spec.rb +22 -0
- data/spec/unit/mongoid/extensions/proc/scoping_spec.rb +34 -0
- data/spec/unit/mongoid/extensions/set/conversions_spec.rb +21 -0
- data/spec/unit/mongoid/extensions/string/conversions_spec.rb +28 -0
- data/spec/unit/mongoid/extensions/string/inflections_spec.rb +208 -0
- data/spec/unit/mongoid/extensions/symbol/inflections_spec.rb +107 -0
- data/spec/unit/mongoid/extensions/time_conversions_spec.rb +186 -0
- data/spec/unit/mongoid/extensions/true_class/equality_spec.rb +35 -0
- data/spec/unit/mongoid/extras_spec.rb +102 -0
- data/spec/unit/mongoid/factory_spec.rb +31 -0
- data/spec/unit/mongoid/field_spec.rb +169 -0
- data/spec/unit/mongoid/fields_spec.rb +181 -0
- data/spec/unit/mongoid/finders_spec.rb +439 -0
- data/spec/unit/mongoid/hierarchy_spec.rb +68 -0
- data/spec/unit/mongoid/identity_spec.rb +109 -0
- data/spec/unit/mongoid/indexes_spec.rb +99 -0
- data/spec/unit/mongoid/javascript_spec.rb +48 -0
- data/spec/unit/mongoid/logger_spec.rb +38 -0
- data/spec/unit/mongoid/matchers/all_spec.rb +27 -0
- data/spec/unit/mongoid/matchers/default_spec.rb +27 -0
- data/spec/unit/mongoid/matchers/exists_spec.rb +56 -0
- data/spec/unit/mongoid/matchers/gt_spec.rb +39 -0
- data/spec/unit/mongoid/matchers/gte_spec.rb +49 -0
- data/spec/unit/mongoid/matchers/in_spec.rb +27 -0
- data/spec/unit/mongoid/matchers/lt_spec.rb +39 -0
- data/spec/unit/mongoid/matchers/lte_spec.rb +49 -0
- data/spec/unit/mongoid/matchers/ne_spec.rb +27 -0
- data/spec/unit/mongoid/matchers/nin_spec.rb +27 -0
- data/spec/unit/mongoid/matchers/size_spec.rb +27 -0
- data/spec/unit/mongoid/matchers_spec.rb +329 -0
- data/spec/unit/mongoid/memoization_spec.rb +75 -0
- data/spec/unit/mongoid/named_scope_spec.rb +123 -0
- data/spec/unit/mongoid/paranoia_spec.rb +108 -0
- data/spec/unit/mongoid/paths_spec.rb +272 -0
- data/spec/unit/mongoid/persistence/insert_embedded_spec.rb +154 -0
- data/spec/unit/mongoid/persistence/insert_spec.rb +144 -0
- data/spec/unit/mongoid/persistence/remove_all_spec.rb +82 -0
- data/spec/unit/mongoid/persistence/remove_embedded_spec.rb +152 -0
- data/spec/unit/mongoid/persistence/remove_spec.rb +89 -0
- data/spec/unit/mongoid/persistence/update_spec.rb +177 -0
- data/spec/unit/mongoid/persistence_spec.rb +452 -0
- data/spec/unit/mongoid/scope_spec.rb +240 -0
- data/spec/unit/mongoid/serialization_spec.rb +43 -0
- data/spec/unit/mongoid/state_spec.rb +94 -0
- data/spec/unit/mongoid/timestamps_spec.rb +30 -0
- data/spec/unit/mongoid/validations/associated_spec.rb +103 -0
- data/spec/unit/mongoid/validations/uniqueness_spec.rb +201 -0
- data/spec/unit/mongoid/validations_spec.rb +43 -0
- data/spec/unit/mongoid/versioning_spec.rb +41 -0
- data/spec/unit/mongoid_spec.rb +46 -0
- metadata +433 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Mongoid::Atomicity do
|
|
4
|
+
|
|
5
|
+
describe "#_updates" do
|
|
6
|
+
|
|
7
|
+
context "when the root and embedded documets have changed" do
|
|
8
|
+
|
|
9
|
+
before do
|
|
10
|
+
@person = Person.new(:title => "Grand Poobah")
|
|
11
|
+
@person.instance_variable_set(:@new_record, false)
|
|
12
|
+
@person.title = "Sir"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "returns a hash of field names and new values" do
|
|
16
|
+
@person._updates.should ==
|
|
17
|
+
{ "$set" => { "title" => "Sir" } }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context "with a new embedded document" do
|
|
21
|
+
|
|
22
|
+
context "when the document is an embeds many" do
|
|
23
|
+
|
|
24
|
+
before do
|
|
25
|
+
@address = Address.new(:street => "Oxford St")
|
|
26
|
+
@person.addresses << @address
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "returns a hash of field names and new values" do
|
|
30
|
+
@person._updates.should ==
|
|
31
|
+
{
|
|
32
|
+
"$set" => { "title" => "Sir" },
|
|
33
|
+
"$pushAll" => { "addresses" => [{ "_id" => "oxford-st", "street" => "Oxford St" }]}
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
context "when the document is an embeds one" do
|
|
39
|
+
|
|
40
|
+
before do
|
|
41
|
+
@name = Name.new(:first_name => "Lionel")
|
|
42
|
+
@person.name = @name
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "returns a hash of field names and new values" do
|
|
46
|
+
@person._updates.should ==
|
|
47
|
+
{
|
|
48
|
+
"$set" => {
|
|
49
|
+
"title" => "Sir",
|
|
50
|
+
"name" => { "_id" => "lionel", "first_name" => "Lionel" }
|
|
51
|
+
},
|
|
52
|
+
}
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
context "with an updated embedded document" do
|
|
58
|
+
|
|
59
|
+
before do
|
|
60
|
+
@address = Address.new(:street => "Oxford St")
|
|
61
|
+
@person.addresses << @address
|
|
62
|
+
@address.instance_variable_set(:@new_record, false)
|
|
63
|
+
@address.street = "Bond St"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "returns a hash of field names and new values" do
|
|
67
|
+
@person._updates.should ==
|
|
68
|
+
{ "$set" => { "title" => "Sir", "addresses.0.street" => "Bond St" } }
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
context "with an multi-level updated embeded document" do
|
|
72
|
+
|
|
73
|
+
before do
|
|
74
|
+
@location = Location.new(:name => "Home")
|
|
75
|
+
@location.instance_variable_set(:@new_record, false)
|
|
76
|
+
@address.locations << @location
|
|
77
|
+
@location.name = "Work"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "returns the proper hash with locations" do
|
|
81
|
+
@person._updates.should ==
|
|
82
|
+
{ "$set" => {
|
|
83
|
+
"title" => "Sir",
|
|
84
|
+
"addresses.0.street" => "Bond St",
|
|
85
|
+
"addresses.0.locations.0.name" => "Work" }
|
|
86
|
+
}
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
context "with an multi-level new bottom embedded document" do
|
|
91
|
+
|
|
92
|
+
before do
|
|
93
|
+
@location = Location.new(:name => "Home")
|
|
94
|
+
@address.locations << @location
|
|
95
|
+
@location.name = "Work"
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "returns the proper hash with locations" do
|
|
99
|
+
@person._updates.should ==
|
|
100
|
+
{
|
|
101
|
+
"$set" => {
|
|
102
|
+
"title" => "Sir",
|
|
103
|
+
"addresses.0.street" => "Bond St"
|
|
104
|
+
},
|
|
105
|
+
"$pushAll" => {
|
|
106
|
+
"addresses.0.locations" => [{ "_id" => @location.id, "name" => "Work" }]
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
context "with multi-level new documents" do
|
|
113
|
+
|
|
114
|
+
before do
|
|
115
|
+
@location = Location.new(:name => "Home")
|
|
116
|
+
@new_address = Address.new(:street => "Another")
|
|
117
|
+
@new_address.locations << @location
|
|
118
|
+
@person.addresses << @new_address
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it "returns the proper hash with locations" do
|
|
122
|
+
@address.stubs(:_sets).returns({})
|
|
123
|
+
@person._updates.should ==
|
|
124
|
+
{
|
|
125
|
+
"$set" => {
|
|
126
|
+
"title" => "Sir",
|
|
127
|
+
},
|
|
128
|
+
"$pushAll" => {
|
|
129
|
+
"addresses" => [{
|
|
130
|
+
"_id" => @new_address.id,
|
|
131
|
+
"street" => "Another",
|
|
132
|
+
"locations" => [
|
|
133
|
+
"_id" => @location.id,
|
|
134
|
+
"name" => "Home"
|
|
135
|
+
]
|
|
136
|
+
}]
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it "returns the proper hash with locations and queue" do
|
|
142
|
+
@person._updates.should ==
|
|
143
|
+
{
|
|
144
|
+
"$set" => {
|
|
145
|
+
"title" => "Sir",
|
|
146
|
+
"addresses.0.street" => "Bond St"
|
|
147
|
+
},
|
|
148
|
+
:other => {
|
|
149
|
+
"addresses" => [{
|
|
150
|
+
"_id" => @new_address.id,
|
|
151
|
+
"street" => "Another",
|
|
152
|
+
"locations" => [
|
|
153
|
+
"_id" => @location.id,
|
|
154
|
+
"name" => "Home"
|
|
155
|
+
]
|
|
156
|
+
}]
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
@@ -0,0 +1,646 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Mongoid::Attributes do
|
|
4
|
+
|
|
5
|
+
describe ".accepts_nested_attributes_for" do
|
|
6
|
+
|
|
7
|
+
before do
|
|
8
|
+
@person = Person.new
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "adds a setter for the association attributes" do
|
|
12
|
+
@person.should respond_to(:addresses_attributes=)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe "#association_attributes=" do
|
|
16
|
+
|
|
17
|
+
context "on a embeds many association" do
|
|
18
|
+
|
|
19
|
+
context "when a reject block supplied" do
|
|
20
|
+
|
|
21
|
+
before do
|
|
22
|
+
@attributes = {
|
|
23
|
+
"0" => { "city" => "San Francisco" }
|
|
24
|
+
}
|
|
25
|
+
@person.addresses_attributes = @attributes
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "removes the attributes that match" do
|
|
29
|
+
@person.addresses.should be_empty
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
context "when association is empty" do
|
|
35
|
+
|
|
36
|
+
before do
|
|
37
|
+
@attributes = {
|
|
38
|
+
"0" => { "street" => "Folsom", "city" => "San Francisco" }
|
|
39
|
+
}
|
|
40
|
+
@person.addresses_attributes = @attributes
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "adds a new document to the association" do
|
|
44
|
+
address = @person.addresses.first
|
|
45
|
+
address.street.should == "Folsom"
|
|
46
|
+
address.city.should == "San Francisco"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
context "when association is not empty" do
|
|
52
|
+
|
|
53
|
+
before do
|
|
54
|
+
@person = Person.new
|
|
55
|
+
@person.addresses.build(:street => "Broadway", :city => "New York")
|
|
56
|
+
@attributes = {
|
|
57
|
+
"0" => { "street" => "Folsom", "city" => "San Francisco" }
|
|
58
|
+
}
|
|
59
|
+
@person.addresses_attributes = @attributes
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "updates the existing attributes on the association" do
|
|
63
|
+
@person.addresses.size.should == 1
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
context "when :allow_destroy is enabled" do
|
|
69
|
+
before do
|
|
70
|
+
@person = Person.new(:title => "Sir", :ssn => "555-66-9999")
|
|
71
|
+
@person.favorites.build(:title => "Ice Cream")
|
|
72
|
+
@person.favorites.build(:title => "Jello")
|
|
73
|
+
@person.favorites.build(:title => "Ducce de Lecce")
|
|
74
|
+
@attributes = {
|
|
75
|
+
"0" => { "_destroy" => "true" },
|
|
76
|
+
"1" => { "_destroy" => "true" }
|
|
77
|
+
}
|
|
78
|
+
@person.favorites_attributes = @attributes
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "removes the items that have _destroy => true set" do
|
|
82
|
+
@person.favorites.class.should == Array
|
|
83
|
+
@person.favorites.size.should == 1
|
|
84
|
+
@person.favorites.first.title.should == "Ducce de Lecce"
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
context "when :limit is set to 5" do
|
|
89
|
+
before do
|
|
90
|
+
@person = Person.new
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it "allows adding 5 favorites" do
|
|
94
|
+
@attributes = {
|
|
95
|
+
"0" => { "title" => "Ice Cream" },
|
|
96
|
+
"1" => { "title" => "Jello" },
|
|
97
|
+
"2" => { "title" => "Sorbet" },
|
|
98
|
+
"3" => { "title" => "Cake" },
|
|
99
|
+
"4" => { "title" => "Tim Tams" }
|
|
100
|
+
}
|
|
101
|
+
@person.favorites_attributes = @attributes
|
|
102
|
+
@person.favorites.size.should == 5
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it "it raises exception when adding more than 5 favorites" do
|
|
106
|
+
@attributes = {
|
|
107
|
+
"0" => { "title" => "Ice Cream" },
|
|
108
|
+
"1" => { "title" => "Jello" },
|
|
109
|
+
"2" => { "title" => "Sorbet" },
|
|
110
|
+
"3" => { "title" => "Cake" },
|
|
111
|
+
"4" => { "title" => "Tim Tams" },
|
|
112
|
+
"5" => { "title" => "Milo" }
|
|
113
|
+
}
|
|
114
|
+
lambda { @person.favorites_attributes = @attributes }.should
|
|
115
|
+
raise_error(Mongoid::Errors::TooManyNestedAttributeRecords)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
context "on a has one association" do
|
|
122
|
+
|
|
123
|
+
before do
|
|
124
|
+
@person = Person.new
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it "can be added if :update_only is false" do
|
|
128
|
+
@person.pet_attributes = { "name" => "Darwin" }
|
|
129
|
+
@person.pet.name.should == "Darwin"
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
it "can be updated if :update_only is false" do
|
|
133
|
+
@person.pet_attributes = { "name" => "Darwin" }
|
|
134
|
+
@person.pet_attributes = { "name" => "Zulu" }
|
|
135
|
+
@person.pet.name.should == "Zulu"
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it "can not be added if :update_only is true" do
|
|
139
|
+
@person.name_attributes = { "first_name" => "Fernando", "last_name" => "Torres" }
|
|
140
|
+
@person.name.should be_blank
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
it "can be updated if :update_only is true" do
|
|
144
|
+
@person = Person.new(:name => { "first_name" => "Marco", "last_name" => "Polo" })
|
|
145
|
+
@person.name_attributes = { "first_name" => "Fernando", "last_name" => "Torres" }
|
|
146
|
+
@person.name.first_name.should == "Fernando"
|
|
147
|
+
@person.name.last_name.should == "Torres"
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
describe ".attr_protected" do
|
|
154
|
+
|
|
155
|
+
context "when the field is not _id" do
|
|
156
|
+
|
|
157
|
+
before do
|
|
158
|
+
@person = Person.new(:security_code => "ABBA")
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
it "prevents setting via mass assignment" do
|
|
162
|
+
@person.security_code.should be_nil
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
context "when the field is _id" do
|
|
167
|
+
|
|
168
|
+
before do
|
|
169
|
+
@game = Game.new(:_id => "ABBA")
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
it "prevents setting via mass assignment" do
|
|
173
|
+
@game._id.should_not == "ABBA"
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
context "when using instantiate" do
|
|
178
|
+
|
|
179
|
+
before do
|
|
180
|
+
@person = Person.instantiate("_id" => "1", "security_code" => "ABBA")
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
it "ignores any protected attribute" do
|
|
184
|
+
@person.security_code.should == "ABBA"
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
describe "#_id" do
|
|
190
|
+
|
|
191
|
+
before do
|
|
192
|
+
@person = Person.new
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
it "delegates to #id" do
|
|
196
|
+
@person._id.should == @person.id
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
describe "#_id=" do
|
|
202
|
+
|
|
203
|
+
before do
|
|
204
|
+
@person = Person.new
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
it "delegates to #id=" do
|
|
208
|
+
@id = BSON::ObjectID.new.to_s
|
|
209
|
+
@person._id = @id
|
|
210
|
+
@person.id.should == @id
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
describe "#method_missing" do
|
|
216
|
+
|
|
217
|
+
before do
|
|
218
|
+
Mongoid.configure.allow_dynamic_fields = true
|
|
219
|
+
@attributes = {
|
|
220
|
+
:testing => "Testing"
|
|
221
|
+
}
|
|
222
|
+
@person = Person.new(@attributes)
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
context "when an attribute exists" do
|
|
226
|
+
|
|
227
|
+
it "allows the getter" do
|
|
228
|
+
@person.testing.should == "Testing"
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
it "allows the setter" do
|
|
232
|
+
@person.testing = "Test"
|
|
233
|
+
@person.testing.should == "Test"
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
describe "#process" do
|
|
241
|
+
|
|
242
|
+
context "when passing non accessible fields" do
|
|
243
|
+
|
|
244
|
+
before do
|
|
245
|
+
@person = Person.new(:owner_id => 6)
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
it "does not set the value" do
|
|
249
|
+
@person.owner_id.should be_nil
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
context "when attributes dont have fields defined" do
|
|
254
|
+
|
|
255
|
+
before do
|
|
256
|
+
@attributes = {
|
|
257
|
+
:nofieldstring => "Testing",
|
|
258
|
+
:nofieldint => 5,
|
|
259
|
+
:employer => Employer.new
|
|
260
|
+
}
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
context "when allowing dynamic fields" do
|
|
264
|
+
|
|
265
|
+
before do
|
|
266
|
+
Mongoid.configure.allow_dynamic_fields = true
|
|
267
|
+
@person = Person.new(@attributes)
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
context "when attribute is a string" do
|
|
271
|
+
|
|
272
|
+
it "adds the string to the attributes" do
|
|
273
|
+
@person.attributes[:nofieldstring].should == "Testing"
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
context "when attribute is not a string" do
|
|
279
|
+
|
|
280
|
+
it "adds a cast value to the attributes" do
|
|
281
|
+
@person.attributes[:nofieldint].should == 5
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
context "when not allowing dynamic fields" do
|
|
289
|
+
|
|
290
|
+
before do
|
|
291
|
+
Mongoid.configure.allow_dynamic_fields = false
|
|
292
|
+
Person.fields.delete(:nofieldstring)
|
|
293
|
+
@attributes = {
|
|
294
|
+
:nofieldstring => "Testing"
|
|
295
|
+
}
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
after do
|
|
299
|
+
Mongoid.configure.allow_dynamic_fields = true
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
it "raises an error" do
|
|
303
|
+
lambda { Person.new(@attributes) }.should raise_error
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
context "when supplied hash has values" do
|
|
311
|
+
|
|
312
|
+
before do
|
|
313
|
+
@attributes = {
|
|
314
|
+
:_id => "1",
|
|
315
|
+
:title => "value",
|
|
316
|
+
:age => "30",
|
|
317
|
+
:terms => "true",
|
|
318
|
+
:score => "",
|
|
319
|
+
:name => {
|
|
320
|
+
:_id => "2", :first_name => "Test", :last_name => "User"
|
|
321
|
+
},
|
|
322
|
+
:addresses => [
|
|
323
|
+
{ :_id => "3", :street => "First Street" },
|
|
324
|
+
{ :_id => "4", :street => "Second Street" }
|
|
325
|
+
]
|
|
326
|
+
}
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
it "returns properly cast attributes" do
|
|
330
|
+
attrs = Person.new(@attributes).attributes
|
|
331
|
+
attrs[:age].should == 30
|
|
332
|
+
attrs[:terms].should == true
|
|
333
|
+
attrs[:_id].should == "1"
|
|
334
|
+
attrs[:score].should be_nil
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
context "when associations provided in the attributes" do
|
|
340
|
+
|
|
341
|
+
context "when association is a has_one" do
|
|
342
|
+
|
|
343
|
+
before do
|
|
344
|
+
@name = Name.new(:first_name => "Testy")
|
|
345
|
+
@attributes = {
|
|
346
|
+
:name => @name
|
|
347
|
+
}
|
|
348
|
+
@person = Person.new(@attributes)
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
it "sets the associations" do
|
|
352
|
+
@person.name.should == @name
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
context "when association is a references_one" do
|
|
358
|
+
|
|
359
|
+
before do
|
|
360
|
+
@game = Game.new(:score => 100)
|
|
361
|
+
@attributes = {
|
|
362
|
+
:game => @game
|
|
363
|
+
}
|
|
364
|
+
@person = Person.new(@attributes)
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
it "sets the associations" do
|
|
368
|
+
@person.game.should == @game
|
|
369
|
+
@game.person.should == @person
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
context "when association is a embedded_in" do
|
|
375
|
+
|
|
376
|
+
before do
|
|
377
|
+
@person = Person.new
|
|
378
|
+
@name = Name.new(:first_name => "Tyler", :person => @person)
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
it "sets the association" do
|
|
382
|
+
@name.person.should == @person
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
context "when non-associations provided in the attributes" do
|
|
390
|
+
|
|
391
|
+
before do
|
|
392
|
+
@employer = Employer.new
|
|
393
|
+
@attributes = { :employer_id => @employer.id, :title => "Sir" }
|
|
394
|
+
@person = Person.new(@attributes)
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
it "calls the setter for the association" do
|
|
398
|
+
@person.employer_id.should == "1"
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
context "when an empty array is provided in the attributes" do
|
|
404
|
+
|
|
405
|
+
before do
|
|
406
|
+
@attributes = {
|
|
407
|
+
:aliases => []
|
|
408
|
+
}
|
|
409
|
+
@person = Person.new(@attributes)
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
it "sets the empty array" do
|
|
413
|
+
@person.aliases.should == []
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
context "when an empty hash is provided in the attributes" do
|
|
419
|
+
|
|
420
|
+
before do
|
|
421
|
+
@attributes = {
|
|
422
|
+
:map => {}
|
|
423
|
+
}
|
|
424
|
+
@person = Person.new(@attributes)
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
it "sets the empty hash" do
|
|
428
|
+
@person.map.should == {}
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
context "updating when attributes already exist" do
|
|
436
|
+
|
|
437
|
+
before do
|
|
438
|
+
@person = Person.new(:title => "Sir")
|
|
439
|
+
@attributes = { :dob => "2000-01-01" }
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
it "only overwrites supplied attributes" do
|
|
443
|
+
@person.process(@attributes)
|
|
444
|
+
@person.title.should == "Sir"
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
describe "#read_attribute" do
|
|
450
|
+
|
|
451
|
+
context "when attribute does not exist" do
|
|
452
|
+
|
|
453
|
+
before do
|
|
454
|
+
@person = Person.new
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
it "returns the default value" do
|
|
458
|
+
@person.age.should == 100
|
|
459
|
+
@person.pets.should == false
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
context "when attribute is not accessible" do
|
|
465
|
+
|
|
466
|
+
before do
|
|
467
|
+
@person = Person.new
|
|
468
|
+
@person.owner_id = 5
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
it "returns the value" do
|
|
472
|
+
@person.read_attribute(:owner_id).should == 5
|
|
473
|
+
end
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
describe "#attribute_present?" do
|
|
479
|
+
context "when attribute does not exist" do
|
|
480
|
+
before do
|
|
481
|
+
@person = Person.new
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
it "returns false" do
|
|
485
|
+
@person.attribute_present?(:owner_id).should be_false
|
|
486
|
+
end
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
context "when attribute does exist" do
|
|
490
|
+
before do
|
|
491
|
+
@person = Person.new
|
|
492
|
+
@person.owner_id = 5
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
it "returns true" do
|
|
496
|
+
@person.attribute_present?(:owner_id).should be_true
|
|
497
|
+
end
|
|
498
|
+
end
|
|
499
|
+
end
|
|
500
|
+
|
|
501
|
+
describe "#remove_attribute" do
|
|
502
|
+
|
|
503
|
+
context "when the attribute exists" do
|
|
504
|
+
|
|
505
|
+
it "removes the attribute" do
|
|
506
|
+
person = Person.new(:title => "Sir")
|
|
507
|
+
person.remove_attribute(:title)
|
|
508
|
+
person.title.should be_nil
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
end
|
|
512
|
+
|
|
513
|
+
context "when the attribute does not exist" do
|
|
514
|
+
|
|
515
|
+
it "does nothing" do
|
|
516
|
+
person = Person.new
|
|
517
|
+
person.remove_attribute(:title)
|
|
518
|
+
person.title.should be_nil
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
end
|
|
522
|
+
|
|
523
|
+
end
|
|
524
|
+
|
|
525
|
+
describe "#write_attribute" do
|
|
526
|
+
|
|
527
|
+
context "when attribute does not exist" do
|
|
528
|
+
|
|
529
|
+
before do
|
|
530
|
+
@person = Person.new
|
|
531
|
+
end
|
|
532
|
+
|
|
533
|
+
it "returns the default value" do
|
|
534
|
+
@person.age.should == 100
|
|
535
|
+
end
|
|
536
|
+
|
|
537
|
+
end
|
|
538
|
+
|
|
539
|
+
context "when setting the attribute to nil" do
|
|
540
|
+
|
|
541
|
+
before do
|
|
542
|
+
@person = Person.new(:age => nil)
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
it "does not use the default value" do
|
|
546
|
+
@person.age.should be_nil
|
|
547
|
+
end
|
|
548
|
+
end
|
|
549
|
+
|
|
550
|
+
context "when field has a default value" do
|
|
551
|
+
|
|
552
|
+
before do
|
|
553
|
+
@person = Person.new
|
|
554
|
+
end
|
|
555
|
+
|
|
556
|
+
it "should allow overwriting of the default value" do
|
|
557
|
+
@person.terms = true
|
|
558
|
+
@person.terms.should be_true
|
|
559
|
+
end
|
|
560
|
+
|
|
561
|
+
end
|
|
562
|
+
|
|
563
|
+
end
|
|
564
|
+
|
|
565
|
+
[:attributes=, :write_attributes].each do |method|
|
|
566
|
+
describe "##{method}" do
|
|
567
|
+
|
|
568
|
+
context "typecasting" do
|
|
569
|
+
|
|
570
|
+
before do
|
|
571
|
+
@person = Person.new
|
|
572
|
+
@attributes = { :age => "50" }
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
it "properly casts values" do
|
|
576
|
+
@person.send(method, @attributes)
|
|
577
|
+
@person.age.should == 50
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
it "allows passing of nil" do
|
|
581
|
+
@person.send(method, nil)
|
|
582
|
+
@person.age.should == 100
|
|
583
|
+
end
|
|
584
|
+
|
|
585
|
+
end
|
|
586
|
+
|
|
587
|
+
context "on a parent document" do
|
|
588
|
+
|
|
589
|
+
context "when the parent has a has many through a has one" do
|
|
590
|
+
|
|
591
|
+
before do
|
|
592
|
+
@owner = PetOwner.new(:title => "Mr")
|
|
593
|
+
@pet = Pet.new(:name => "Fido")
|
|
594
|
+
@owner.pet = @pet
|
|
595
|
+
@vet_visit = VetVisit.new(:date => Date.today)
|
|
596
|
+
@pet.vet_visits = [@vet_visit]
|
|
597
|
+
end
|
|
598
|
+
|
|
599
|
+
it "does not overwrite child attributes if not in the hash" do
|
|
600
|
+
@owner.send(method, { :pet => { :name => "Bingo" } })
|
|
601
|
+
@owner.pet.name.should == "Bingo"
|
|
602
|
+
@owner.pet.vet_visits.size.should == 1
|
|
603
|
+
end
|
|
604
|
+
end
|
|
605
|
+
end
|
|
606
|
+
|
|
607
|
+
context "on a child document" do
|
|
608
|
+
|
|
609
|
+
context "when child is part of a has one" do
|
|
610
|
+
|
|
611
|
+
before do
|
|
612
|
+
@person = Person.new(:title => "Sir", :age => 30)
|
|
613
|
+
@name = Name.new(:first_name => "Test", :last_name => "User")
|
|
614
|
+
@person.name = @name
|
|
615
|
+
end
|
|
616
|
+
|
|
617
|
+
it "sets the child attributes on the parent" do
|
|
618
|
+
@name.send(method, :first_name => "Test2", :last_name => "User2")
|
|
619
|
+
@person.attributes[:name].should ==
|
|
620
|
+
{ "_id" => "test-user", "first_name" => "Test2", "last_name" => "User2" }
|
|
621
|
+
end
|
|
622
|
+
|
|
623
|
+
end
|
|
624
|
+
|
|
625
|
+
context "when child is part of a has many" do
|
|
626
|
+
|
|
627
|
+
before do
|
|
628
|
+
@person = Person.new(:title => "Sir")
|
|
629
|
+
@address = Address.new(:street => "Test")
|
|
630
|
+
@person.addresses << @address
|
|
631
|
+
end
|
|
632
|
+
|
|
633
|
+
it "updates the child attributes on the parent" do
|
|
634
|
+
@address.send(method, "street" => "Test2")
|
|
635
|
+
@person.attributes[:addresses].should ==
|
|
636
|
+
[ { "_id" => "test", "street" => "Test2" } ]
|
|
637
|
+
end
|
|
638
|
+
|
|
639
|
+
end
|
|
640
|
+
|
|
641
|
+
end
|
|
642
|
+
end
|
|
643
|
+
|
|
644
|
+
end
|
|
645
|
+
|
|
646
|
+
end
|