mongomodel 0.5.5 → 0.5.6
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.
- checksums.yaml +5 -5
- data/.travis.yml +23 -11
- data/gemfiles/rails-3.2.gemfile +2 -2
- data/gemfiles/rails-4-observers.gemfile +1 -1
- data/gemfiles/rails-4.1.gemfile +2 -2
- data/gemfiles/{mongoid.gemfile → rails-4.2.gemfile} +2 -3
- data/gemfiles/{mongo_mapper.gemfile → rails-5.0.gemfile} +2 -3
- data/gemfiles/rails-5.1.gemfile +10 -0
- data/gemfiles/rails-5.2.gemfile +10 -0
- data/lib/mongomodel.rb +15 -15
- data/lib/mongomodel/attributes/mongo.rb +7 -7
- data/lib/mongomodel/attributes/store.rb +4 -4
- data/lib/mongomodel/attributes/typecasting.rb +7 -7
- data/lib/mongomodel/compatibility/mongo_mapper.rb +3 -3
- data/lib/mongomodel/compatibility/mongoid.rb +3 -3
- data/lib/mongomodel/concerns/abstract_class.rb +3 -3
- data/lib/mongomodel/concerns/activemodel.rb +4 -4
- data/lib/mongomodel/concerns/associations.rb +8 -8
- data/lib/mongomodel/concerns/associations/base/association.rb +5 -5
- data/lib/mongomodel/concerns/associations/base/definition.rb +4 -4
- data/lib/mongomodel/concerns/associations/base/proxy.rb +1 -1
- data/lib/mongomodel/concerns/associations/belongs_to.rb +19 -19
- data/lib/mongomodel/concerns/associations/has_many_by_foreign_key.rb +36 -36
- data/lib/mongomodel/concerns/associations/has_many_by_ids.rb +34 -34
- data/lib/mongomodel/concerns/attribute_methods.rb +10 -10
- data/lib/mongomodel/concerns/attribute_methods/before_type_cast.rb +4 -4
- data/lib/mongomodel/concerns/attribute_methods/dirty.rb +95 -13
- data/lib/mongomodel/concerns/attribute_methods/forbidden.rb +1 -1
- data/lib/mongomodel/concerns/attribute_methods/multi_parameter_assignment.rb +6 -6
- data/lib/mongomodel/concerns/attribute_methods/nested.rb +18 -18
- data/lib/mongomodel/concerns/attribute_methods/protected.rb +3 -3
- data/lib/mongomodel/concerns/attribute_methods/query.rb +3 -3
- data/lib/mongomodel/concerns/attribute_methods/read.rb +4 -4
- data/lib/mongomodel/concerns/attribute_methods/write.rb +4 -4
- data/lib/mongomodel/concerns/attributes.rb +18 -18
- data/lib/mongomodel/concerns/callbacks.rb +7 -7
- data/lib/mongomodel/concerns/document_parent.rb +2 -2
- data/lib/mongomodel/concerns/logging.rb +2 -2
- data/lib/mongomodel/concerns/map_reduce.rb +11 -11
- data/lib/mongomodel/concerns/pretty_inspect.rb +3 -3
- data/lib/mongomodel/concerns/properties.rb +18 -18
- data/lib/mongomodel/concerns/record_status.rb +9 -13
- data/lib/mongomodel/concerns/serialization.rb +4 -4
- data/lib/mongomodel/concerns/timestamps.rb +4 -4
- data/lib/mongomodel/concerns/translation.rb +2 -2
- data/lib/mongomodel/concerns/validations.rb +5 -5
- data/lib/mongomodel/concerns/validations/associated.rb +1 -1
- data/lib/mongomodel/document.rb +6 -6
- data/lib/mongomodel/document/callbacks.rb +15 -21
- data/lib/mongomodel/document/collection_modifiers.rb +5 -5
- data/lib/mongomodel/document/dynamic_finders.rb +1 -1
- data/lib/mongomodel/document/indexes.rb +19 -19
- data/lib/mongomodel/document/optimistic_locking.rb +7 -7
- data/lib/mongomodel/document/persistence.rb +23 -23
- data/lib/mongomodel/document/scopes.rb +20 -20
- data/lib/mongomodel/document/validations.rb +6 -6
- data/lib/mongomodel/document/validations/uniqueness.rb +11 -11
- data/lib/mongomodel/embedded_document.rb +11 -11
- data/lib/mongomodel/locale/en.yml +0 -1
- data/lib/mongomodel/log_subscriber.rb +5 -5
- data/lib/mongomodel/railtie.rb +13 -13
- data/lib/mongomodel/support/collection.rb +31 -31
- data/lib/mongomodel/support/configuration.rb +11 -11
- data/lib/mongomodel/support/core_extensions.rb +1 -1
- data/lib/mongomodel/support/dynamic_finder.rb +12 -12
- data/lib/mongomodel/support/exceptions.rb +6 -6
- data/lib/mongomodel/support/instrumented_collection.rb +20 -20
- data/lib/mongomodel/support/map.rb +33 -33
- data/lib/mongomodel/support/mongo_operator.rb +6 -6
- data/lib/mongomodel/support/mongo_options.rb +18 -18
- data/lib/mongomodel/support/mongo_order.rb +16 -16
- data/lib/mongomodel/support/paginator.rb +8 -8
- data/lib/mongomodel/support/reference.rb +10 -10
- data/lib/mongomodel/support/scope.rb +37 -37
- data/lib/mongomodel/support/scope/array_methods.rb +1 -1
- data/lib/mongomodel/support/scope/batches.rb +1 -1
- data/lib/mongomodel/support/scope/dynamic_finders.rb +1 -1
- data/lib/mongomodel/support/scope/finder_methods.rb +7 -7
- data/lib/mongomodel/support/scope/load_methods.rb +1 -1
- data/lib/mongomodel/support/scope/pagination.rb +1 -1
- data/lib/mongomodel/support/scope/query_methods.rb +6 -6
- data/lib/mongomodel/support/scope/spawn_methods.rb +8 -8
- data/lib/mongomodel/support/types.rb +2 -2
- data/lib/mongomodel/support/types/array.rb +1 -1
- data/lib/mongomodel/support/types/boolean.rb +3 -3
- data/lib/mongomodel/support/types/custom.rb +3 -3
- data/lib/mongomodel/support/types/date.rb +2 -2
- data/lib/mongomodel/support/types/date_time.rb +6 -16
- data/lib/mongomodel/support/types/float.rb +1 -1
- data/lib/mongomodel/support/types/hash.rb +1 -1
- data/lib/mongomodel/support/types/integer.rb +13 -10
- data/lib/mongomodel/support/types/object.rb +5 -5
- data/lib/mongomodel/support/types/rational.rb +3 -3
- data/lib/mongomodel/support/types/time.rb +2 -2
- data/lib/mongomodel/version.rb +1 -1
- data/lib/rails/generators/mongo_model/config/templates/mongomodel.yml +3 -4
- data/lib/rails/generators/mongo_model/model/model_generator.rb +3 -3
- data/mongomodel.gemspec +5 -4
- data/spec/mongomodel/attributes/store_spec.rb +21 -21
- data/spec/mongomodel/concerns/activemodel_spec.rb +4 -4
- data/spec/mongomodel/concerns/associations/base/association_spec.rb +12 -12
- data/spec/mongomodel/concerns/associations/belongs_to_spec.rb +34 -21
- data/spec/mongomodel/concerns/associations/has_many_by_foreign_key_spec.rb +53 -53
- data/spec/mongomodel/concerns/associations/has_many_by_ids_spec.rb +30 -30
- data/spec/mongomodel/concerns/attribute_methods/before_type_cast_spec.rb +7 -7
- data/spec/mongomodel/concerns/attribute_methods/dirty_spec.rb +45 -41
- data/spec/mongomodel/concerns/attribute_methods/multi_parameter_assignment_spec.rb +7 -7
- data/spec/mongomodel/concerns/attribute_methods/nested_spec.rb +31 -31
- data/spec/mongomodel/concerns/attribute_methods/protected_spec.rb +15 -15
- data/spec/mongomodel/concerns/attribute_methods/query_spec.rb +19 -19
- data/spec/mongomodel/concerns/attribute_methods/read_spec.rb +9 -9
- data/spec/mongomodel/concerns/attribute_methods/write_spec.rb +6 -6
- data/spec/mongomodel/concerns/attribute_methods_spec.rb +13 -13
- data/spec/mongomodel/concerns/attributes_spec.rb +34 -34
- data/spec/mongomodel/concerns/callbacks_spec.rb +25 -21
- data/spec/mongomodel/concerns/logging_spec.rb +5 -3
- data/spec/mongomodel/concerns/map_reduce_spec.rb +19 -19
- data/spec/mongomodel/concerns/observing_spec.rb +3 -3
- data/spec/mongomodel/concerns/pretty_inspect_spec.rb +10 -10
- data/spec/mongomodel/concerns/properties_spec.rb +11 -11
- data/spec/mongomodel/concerns/serialization/json_serialization_spec.rb +13 -13
- data/spec/mongomodel/concerns/timestamps_spec.rb +39 -39
- data/spec/mongomodel/concerns/validations_spec.rb +41 -38
- data/spec/mongomodel/document/callbacks_spec.rb +20 -16
- data/spec/mongomodel/document/collection_modifiers_spec.rb +16 -16
- data/spec/mongomodel/document/dynamic_finders_spec.rb +46 -46
- data/spec/mongomodel/document/finders_spec.rb +15 -15
- data/spec/mongomodel/document/indexes_spec.rb +29 -29
- data/spec/mongomodel/document/optimistic_locking_spec.rb +16 -16
- data/spec/mongomodel/document/persistence_spec.rb +39 -39
- data/spec/mongomodel/document/scopes_spec.rb +17 -17
- data/spec/mongomodel/document/validations/uniqueness_spec.rb +46 -46
- data/spec/mongomodel/document/validations_spec.rb +35 -35
- data/spec/mongomodel/document_spec.rb +19 -19
- data/spec/mongomodel/embedded_document_spec.rb +19 -19
- data/spec/mongomodel/mongomodel_spec.rb +7 -6
- data/spec/mongomodel/support/collection_spec.rb +54 -54
- data/spec/mongomodel/support/configuration_spec.rb +1 -1
- data/spec/mongomodel/support/map_spec.rb +66 -66
- data/spec/mongomodel/support/mongo_operator_spec.rb +5 -5
- data/spec/mongomodel/support/mongo_options_spec.rb +42 -42
- data/spec/mongomodel/support/mongo_order_spec.rb +24 -24
- data/spec/mongomodel/support/paginator_spec.rb +15 -15
- data/spec/mongomodel/support/property_spec.rb +29 -23
- data/spec/mongomodel/support/scope_spec.rb +205 -204
- data/spec/spec_helper.rb +13 -2
- data/spec/support/callbacks.rb +3 -8
- data/spec/support/helpers/define_class.rb +7 -7
- data/spec/support/helpers/document_finder_stubs.rb +6 -6
- data/spec/support/helpers/specs_for.rb +1 -1
- data/spec/support/helpers/validations.rb +1 -1
- data/spec/support/matchers/find_with.rb +8 -8
- data/spec/support/matchers/respond_to_boolean.rb +3 -3
- data/spec/support/matchers/run_callbacks.rb +6 -9
- data/spec/support/models.rb +5 -5
- metadata +23 -7
|
@@ -5,58 +5,58 @@ module MongoModel
|
|
|
5
5
|
describe "generating attribute methods" do
|
|
6
6
|
define_class(:TestDocument, described_class) do
|
|
7
7
|
property :foo, String
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
def foo(a); "from method"; end
|
|
10
10
|
end
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
subject { TestDocument.new }
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
it "does not overwrite an existing method" do
|
|
15
15
|
subject.foo(1).should == "from method"
|
|
16
16
|
end
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
context "on a subclass" do
|
|
19
19
|
define_class(:SubDocument, :TestDocument)
|
|
20
20
|
subject { SubDocument.new }
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
it "does not overwrite methods defined on the superclass" do
|
|
23
23
|
subject.foo(1).should == "from method"
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
|
-
|
|
26
|
+
|
|
27
27
|
context "on a class with an included module" do
|
|
28
28
|
module TestModule
|
|
29
29
|
def foo(a); "from method"; end
|
|
30
30
|
end
|
|
31
|
-
|
|
31
|
+
|
|
32
32
|
it "does not overwrite methods defined on the included module" do
|
|
33
33
|
TestDocument.send(:include, TestModule)
|
|
34
34
|
subject.foo(1).should == "from method"
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
|
-
|
|
37
|
+
|
|
38
38
|
context "on a class with an included concern that defines the property" do
|
|
39
39
|
define_module(:TestConcern) do
|
|
40
40
|
extend ActiveSupport::Concern
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
included do
|
|
43
43
|
property :bar, String
|
|
44
44
|
end
|
|
45
|
-
|
|
45
|
+
|
|
46
46
|
def bar(a); "from concern"; end
|
|
47
47
|
end
|
|
48
|
-
|
|
48
|
+
|
|
49
49
|
context "the base class" do
|
|
50
50
|
it "does not overwrite methods defined within the concern" do
|
|
51
51
|
TestDocument.send(:include, TestConcern)
|
|
52
52
|
subject.bar(1).should == "from concern"
|
|
53
53
|
end
|
|
54
54
|
end
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
context "subclasses" do
|
|
57
57
|
define_class(:SubDocument, :TestDocument)
|
|
58
58
|
subject { SubDocument.new }
|
|
59
|
-
|
|
59
|
+
|
|
60
60
|
it "does not overwrite methods defined within the concern" do
|
|
61
61
|
SubDocument.send(:include, TestConcern)
|
|
62
62
|
subject.bar(1).should == "from concern"
|
|
@@ -16,109 +16,109 @@ module MongoModel
|
|
|
16
16
|
Time => Types::Time.new.cast(Time.now),
|
|
17
17
|
DateTime => Types::DateTime.new.cast(DateTime.now.in_time_zone)
|
|
18
18
|
}
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
specs_for(Document, EmbeddedDocument) do
|
|
21
21
|
define_class(:TestDocument, described_class)
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
it "has an attributes store on the instance" do
|
|
24
24
|
doc = TestDocument.new
|
|
25
25
|
doc.attributes.should be_an_instance_of(MongoModel::Attributes::Store)
|
|
26
26
|
end
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
it "converts to mongo representation" do
|
|
29
29
|
doc = TestDocument.new
|
|
30
30
|
doc.to_mongo.should == doc.attributes.to_mongo
|
|
31
31
|
end
|
|
32
|
-
|
|
32
|
+
|
|
33
33
|
AttributeTypes.each do |type, value|
|
|
34
34
|
describe "setting #{type} attributes" do
|
|
35
35
|
define_class(:TestDocument, described_class) do
|
|
36
36
|
property :test_property, type
|
|
37
37
|
end
|
|
38
|
-
|
|
38
|
+
|
|
39
39
|
if specing?(EmbeddedDocument)
|
|
40
40
|
define_class(:ParentDocument, Document) do
|
|
41
41
|
property :child, TestDocument
|
|
42
42
|
end
|
|
43
|
-
|
|
43
|
+
|
|
44
44
|
let(:parent) { ParentDocument.create!(:child => TestDocument.new(:test_property => value)) }
|
|
45
45
|
let(:child) { parent.child }
|
|
46
46
|
let(:reloaded) { ParentDocument.find(parent.id).child }
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
subject { child }
|
|
49
49
|
else
|
|
50
50
|
subject { TestDocument.create!(:test_property => value) }
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
let(:reloaded) { TestDocument.find(subject.id) }
|
|
53
53
|
end
|
|
54
|
-
|
|
54
|
+
|
|
55
55
|
it "reads the correct value from attributes" do
|
|
56
56
|
subject.test_property.should == value
|
|
57
57
|
end
|
|
58
|
-
|
|
58
|
+
|
|
59
59
|
it "reads the correct value after reloading" do
|
|
60
60
|
reloaded.test_property.should == subject.test_property
|
|
61
61
|
end
|
|
62
62
|
end
|
|
63
63
|
end
|
|
64
|
-
|
|
64
|
+
|
|
65
65
|
it "has an attributes store" do
|
|
66
66
|
doc = TestDocument.new
|
|
67
67
|
doc.attributes.should be_an_instance_of(MongoModel::Attributes::Store)
|
|
68
68
|
end
|
|
69
|
-
|
|
69
|
+
|
|
70
70
|
it "duplicates attributes when duplicating object" do
|
|
71
71
|
original = TestDocument.new
|
|
72
72
|
duplicate = original.dup
|
|
73
|
-
|
|
73
|
+
|
|
74
74
|
duplicate.attributes.should_not equal(original.attributes)
|
|
75
75
|
end
|
|
76
|
-
|
|
76
|
+
|
|
77
77
|
describe "initializing" do
|
|
78
78
|
define_class(:Person, EmbeddedDocument) do
|
|
79
79
|
property :name, String
|
|
80
80
|
property :age, Integer, :default => 21
|
|
81
81
|
end
|
|
82
|
-
|
|
82
|
+
|
|
83
83
|
it "is initializable with attributes hash" do
|
|
84
84
|
doc = Person.new(:name => 'Fred', :age => 42)
|
|
85
85
|
doc.name.should == 'Fred'
|
|
86
86
|
doc.age.should == 42
|
|
87
87
|
end
|
|
88
|
-
|
|
88
|
+
|
|
89
89
|
it "uses default attributes when initializing with partial attributes hash" do
|
|
90
90
|
doc = Person.new(:name => 'Maurice')
|
|
91
91
|
doc.age.should == 21
|
|
92
92
|
end
|
|
93
|
-
|
|
93
|
+
|
|
94
94
|
it "loads from mongo representation" do
|
|
95
95
|
doc = Person.from_mongo({ 'name' => 'James', 'age' => 15 })
|
|
96
96
|
doc.name.should == 'James'
|
|
97
97
|
doc.age.should == 15
|
|
98
98
|
end
|
|
99
99
|
end
|
|
100
|
-
|
|
100
|
+
|
|
101
101
|
describe "setting attributes with hash" do
|
|
102
102
|
define_class(:TestDocument, described_class) do
|
|
103
103
|
property :test_property, String
|
|
104
|
-
|
|
104
|
+
|
|
105
105
|
def test_property=(value)
|
|
106
106
|
write_attribute(:test_property, 'set from method')
|
|
107
107
|
end
|
|
108
108
|
end
|
|
109
|
-
|
|
109
|
+
|
|
110
110
|
subject { TestDocument.new }
|
|
111
|
-
|
|
111
|
+
|
|
112
112
|
it "calls custom property methods" do
|
|
113
113
|
subject.attributes = { :test_property => 'property value' }
|
|
114
114
|
subject.test_property.should == 'set from method'
|
|
115
115
|
end
|
|
116
|
-
|
|
116
|
+
|
|
117
117
|
it "uses write_attribute if no such property" do
|
|
118
118
|
subject.attributes = { :non_property => 'property value' }
|
|
119
119
|
subject.read_attribute(:non_property).should == 'property value'
|
|
120
120
|
end
|
|
121
|
-
|
|
121
|
+
|
|
122
122
|
if defined?(ActiveModel::ForbiddenAttributesProtection)
|
|
123
123
|
it "raises ActiveModel::ForbiddenAttributesError when passed an unpermitted strong_params hash" do
|
|
124
124
|
expect {
|
|
@@ -127,35 +127,35 @@ module MongoModel
|
|
|
127
127
|
end
|
|
128
128
|
end
|
|
129
129
|
end
|
|
130
|
-
|
|
130
|
+
|
|
131
131
|
describe "#new" do
|
|
132
132
|
define_class(:TestDocument, described_class)
|
|
133
|
-
|
|
133
|
+
|
|
134
134
|
it "yields the instance to a block if provided" do
|
|
135
135
|
block_called = false
|
|
136
|
-
|
|
136
|
+
|
|
137
137
|
TestDocument.new do |doc|
|
|
138
138
|
block_called = true
|
|
139
139
|
doc.should be_an_instance_of(TestDocument)
|
|
140
140
|
end
|
|
141
|
-
|
|
142
|
-
block_called.should
|
|
141
|
+
|
|
142
|
+
block_called.should be true
|
|
143
143
|
end
|
|
144
144
|
end
|
|
145
|
-
|
|
145
|
+
|
|
146
146
|
context "a frozen instance" do
|
|
147
147
|
define_class(:TestDocument, described_class) do
|
|
148
148
|
property :test_property, String
|
|
149
149
|
end
|
|
150
|
-
|
|
150
|
+
|
|
151
151
|
subject { TestDocument.new(:test_property => 'Test') }
|
|
152
|
-
|
|
152
|
+
|
|
153
153
|
before(:each) { subject.freeze }
|
|
154
|
-
|
|
154
|
+
|
|
155
155
|
it { should be_frozen }
|
|
156
|
-
|
|
156
|
+
|
|
157
157
|
it "does not allow changes to the attributes hash" do
|
|
158
|
-
lambda { subject.attributes[:test_property] = 'Change' }.should raise_error
|
|
158
|
+
lambda { subject.attributes[:test_property] = 'Change' }.should raise_error(RuntimeError)
|
|
159
159
|
end
|
|
160
160
|
end
|
|
161
161
|
end
|
|
@@ -7,11 +7,11 @@ module MongoModel
|
|
|
7
7
|
include MongoModel::CallbackHelpers
|
|
8
8
|
property :name, String
|
|
9
9
|
end
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
define_class(:ParentDocument, Document) do
|
|
12
12
|
property :things, Collection[ChildThingDocument]
|
|
13
13
|
end
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
it "calls callbacks on all embedded documents when adding a new one" do
|
|
16
16
|
parent = ParentDocument.create!
|
|
17
17
|
parent.things = Collection[ChildThingDocument].new
|
|
@@ -22,84 +22,88 @@ module MongoModel
|
|
|
22
22
|
parent.save!
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
describe "callbacks" do
|
|
27
27
|
define_class(:ChildDocument, EmbeddedDocument) do
|
|
28
28
|
include MongoModel::CallbackHelpers
|
|
29
29
|
end
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
define_class(:ParentDocument, Document) do
|
|
32
32
|
property :child, ChildDocument
|
|
33
33
|
end
|
|
34
|
-
|
|
34
|
+
|
|
35
35
|
let(:child) { ChildDocument.new }
|
|
36
36
|
let(:parent) { ParentDocument.create!(:child => child) }
|
|
37
|
-
|
|
37
|
+
|
|
38
38
|
it "runs each type of callback when initializing" do
|
|
39
39
|
instance = ChildDocument.new
|
|
40
40
|
instance.should run_callbacks(:after_initialize)
|
|
41
41
|
end
|
|
42
|
-
|
|
42
|
+
|
|
43
43
|
it "runs each type of callback on find" do
|
|
44
44
|
instance = ParentDocument.find(parent.id).child
|
|
45
45
|
instance.should run_callbacks(:after_initialize, :after_find)
|
|
46
46
|
end
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
it "runs each type of callback when validating a new document" do
|
|
49
49
|
instance = ChildDocument.new
|
|
50
50
|
instance.valid?
|
|
51
51
|
instance.should run_callbacks(:after_initialize, :before_validation, :after_validation)
|
|
52
52
|
end
|
|
53
|
-
|
|
53
|
+
|
|
54
54
|
it "runs each type of callback when validating an existing document" do
|
|
55
55
|
instance = ParentDocument.find(parent.id).child
|
|
56
56
|
instance.valid?
|
|
57
57
|
instance.should run_callbacks(:after_initialize, :after_find, :before_validation, :after_validation)
|
|
58
58
|
end
|
|
59
|
-
|
|
59
|
+
|
|
60
60
|
it "runs each type of callback when creating a document" do
|
|
61
61
|
instance = ParentDocument.create!(:child => ChildDocument.new)
|
|
62
62
|
instance.child.should run_callbacks(:after_initialize, :before_validation, :after_validation, :before_save, :before_create, :after_create, :after_save)
|
|
63
63
|
end
|
|
64
|
-
|
|
64
|
+
|
|
65
65
|
it "runs each type of callback when saving an existing document" do
|
|
66
66
|
instance = ParentDocument.find(parent.id)
|
|
67
67
|
instance.save
|
|
68
68
|
instance.child.should run_callbacks(:after_initialize, :after_find, :before_validation, :after_validation, :before_save, :before_update, :after_update, :after_save)
|
|
69
69
|
end
|
|
70
|
-
|
|
70
|
+
|
|
71
71
|
it "runs each type of callback when destroying a document" do
|
|
72
72
|
instance = ParentDocument.find(parent.id)
|
|
73
73
|
instance.destroy
|
|
74
74
|
instance.child.should run_callbacks(:after_initialize, :after_find, :before_destroy, :after_destroy)
|
|
75
75
|
end
|
|
76
|
-
|
|
76
|
+
|
|
77
77
|
it "does not run destroy callbacks when deleting a document" do
|
|
78
78
|
instance = ParentDocument.find(parent.id)
|
|
79
79
|
instance.delete
|
|
80
80
|
instance.child.should run_callbacks(:after_initialize, :after_find)
|
|
81
81
|
end
|
|
82
82
|
end
|
|
83
|
-
|
|
83
|
+
|
|
84
84
|
[ :before_save, :before_create ].each do |callback|
|
|
85
|
-
context "#{callback} callback
|
|
85
|
+
context "#{callback} callback halts" do
|
|
86
86
|
define_class(:ChildDocument, EmbeddedDocument) do
|
|
87
|
-
|
|
87
|
+
if Gem::Version.new(ActiveSupport::VERSION::STRING) >= Gem::Version.new('5.0.0')
|
|
88
|
+
send(callback) { throw :abort }
|
|
89
|
+
else
|
|
90
|
+
send(callback) { false }
|
|
91
|
+
end
|
|
88
92
|
end
|
|
89
|
-
|
|
93
|
+
|
|
90
94
|
define_class(:ParentDocument, Document) do
|
|
91
95
|
property :child, ChildDocument
|
|
92
96
|
end
|
|
93
|
-
|
|
97
|
+
|
|
94
98
|
let(:child) { ChildDocument.new }
|
|
95
99
|
let(:parent) { ParentDocument.new(:child => child) }
|
|
96
|
-
|
|
100
|
+
|
|
97
101
|
describe "#save" do
|
|
98
102
|
it "returns false" do
|
|
99
|
-
parent.save.should
|
|
103
|
+
parent.save.should be false
|
|
100
104
|
end
|
|
101
105
|
end
|
|
102
|
-
|
|
106
|
+
|
|
103
107
|
describe "#save!" do
|
|
104
108
|
it "raises a MongoModel::DocumentNotSaved exception" do
|
|
105
109
|
lambda { parent.save! }.should raise_error(MongoModel::DocumentNotSaved)
|
|
@@ -4,14 +4,16 @@ module MongoModel
|
|
|
4
4
|
specs_for(Document, EmbeddedDocument) do
|
|
5
5
|
describe "logging" do
|
|
6
6
|
define_class(:TestDocument, described_class)
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
let(:logger) { double('logger').as_null_object }
|
|
9
|
+
|
|
9
10
|
before(:each) { MongoModel.logger = logger }
|
|
10
|
-
|
|
11
|
+
after(:each) { MongoModel.logger = nil }
|
|
12
|
+
|
|
11
13
|
it "has a logger reader on the class" do
|
|
12
14
|
TestDocument.logger.should == logger
|
|
13
15
|
end
|
|
14
|
-
|
|
16
|
+
|
|
15
17
|
it "has a logger reader on the instance" do
|
|
16
18
|
TestDocument.new.logger.should == logger
|
|
17
19
|
end
|
|
@@ -5,20 +5,20 @@ module MongoModel
|
|
|
5
5
|
describe "counting tags" do
|
|
6
6
|
# This example is extracted from the Counting Tags pattern in the
|
|
7
7
|
# MongoDB Cookbook: http://cookbook.mongodb.org/patterns/count_tags/
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
define_class(:Article, Document) do
|
|
10
10
|
property :tags, Collection[String]
|
|
11
11
|
end
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
define_class(:Tag, Struct.new(:name, :count)) do
|
|
14
14
|
include MongoModel::MapReduce
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
self.parent_collection = Article.collection
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
def initialize(name, count)
|
|
19
19
|
super(name, count.to_i)
|
|
20
20
|
end
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
def self.map_function
|
|
23
23
|
<<-MAP
|
|
24
24
|
function() {
|
|
@@ -45,58 +45,58 @@ module MongoModel
|
|
|
45
45
|
REDUCE
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
|
-
|
|
48
|
+
|
|
49
49
|
specify "tag comparison" do
|
|
50
50
|
Tag.new("Tag 1", 1).should == Tag.new("Tag 1", 1)
|
|
51
51
|
Tag.new("Tag 2", 1).should_not == Tag.new("Tag 1", 1)
|
|
52
52
|
Tag.new("Tag 1", 1).should_not == Tag.new("Tag 1", 2)
|
|
53
53
|
end
|
|
54
|
-
|
|
54
|
+
|
|
55
55
|
before do
|
|
56
56
|
Article.create!(:tags => ["Tag 1", "Tag 2"])
|
|
57
57
|
Article.create!(:tags => ["Tag 2"])
|
|
58
58
|
Article.create!(:tags => ["Tag 3"])
|
|
59
59
|
end
|
|
60
|
-
|
|
60
|
+
|
|
61
61
|
it "has a default collection name based on the parent collection" do
|
|
62
62
|
Tag.collection_name.should == "articles._tags"
|
|
63
63
|
end
|
|
64
|
-
|
|
64
|
+
|
|
65
65
|
it "stores the result in a named collection" do
|
|
66
66
|
Tag.collection.name.should == Tag.collection_name
|
|
67
67
|
end
|
|
68
|
-
|
|
68
|
+
|
|
69
69
|
it "allows use of scope methods" do
|
|
70
70
|
Tag.all.should == [Tag.new("Tag 1", 1), Tag.new("Tag 2", 2), Tag.new("Tag 3", 1)]
|
|
71
71
|
Tag.order(:value.desc).first.should == Tag.new("Tag 2", 2)
|
|
72
72
|
Tag.where(:value.gt => 1).should == [Tag.new("Tag 2", 2)]
|
|
73
73
|
end
|
|
74
|
-
|
|
74
|
+
|
|
75
75
|
it "loads previously computed results" do
|
|
76
76
|
expected = Tag.all
|
|
77
77
|
Article.create!(:tags => ["Tag 1"])
|
|
78
78
|
Tag.cached.should == expected
|
|
79
79
|
end
|
|
80
80
|
end
|
|
81
|
-
|
|
81
|
+
|
|
82
82
|
describe "pivot data" do
|
|
83
83
|
# This example is similar to the Pivot Data pattern in the
|
|
84
84
|
# MongoDB Cookbook: http://cookbook.mongodb.org/patterns/pivot/
|
|
85
|
-
|
|
85
|
+
|
|
86
86
|
define_class(:Actor, Document) do
|
|
87
87
|
property :name, String
|
|
88
88
|
property :movies, Collection[String]
|
|
89
89
|
end
|
|
90
|
-
|
|
90
|
+
|
|
91
91
|
define_class(:Movie, Struct.new(:name, :actors)) do
|
|
92
92
|
include MongoModel::MapReduce
|
|
93
|
-
|
|
93
|
+
|
|
94
94
|
self.parent_collection = Actor.collection
|
|
95
|
-
|
|
95
|
+
|
|
96
96
|
def self.from_mongo(attrs)
|
|
97
97
|
new(attrs['_id'], attrs['value']['actors'].sort)
|
|
98
98
|
end
|
|
99
|
-
|
|
99
|
+
|
|
100
100
|
def self.map_function
|
|
101
101
|
<<-MAP
|
|
102
102
|
function() {
|
|
@@ -121,12 +121,12 @@ module MongoModel
|
|
|
121
121
|
REDUCE
|
|
122
122
|
end
|
|
123
123
|
end
|
|
124
|
-
|
|
124
|
+
|
|
125
125
|
before do
|
|
126
126
|
Actor.create!(:name => "Richard Gere", :movies => ['Pretty Woman', 'Runaway Bride', 'Chicago'])
|
|
127
127
|
Actor.create!(:name => "Julia Roberts", :movies => ['Pretty Woman', 'Runaway Bride', 'Erin Brockovich'])
|
|
128
128
|
end
|
|
129
|
-
|
|
129
|
+
|
|
130
130
|
it "pivots data" do
|
|
131
131
|
Movie.all.should include(
|
|
132
132
|
Movie.new("Pretty Woman", ["Julia Roberts", "Richard Gere"]),
|