mongoid 0.4.5 → 0.4.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,14 +1,29 @@
1
1
  require "mongoid/extensions/array/conversions"
2
2
  require "mongoid/extensions/array/parentization"
3
+ require "mongoid/extensions/hash/accessors"
3
4
  require "mongoid/extensions/object/conversions"
4
5
  require "mongoid/extensions/object/parentization"
6
+ require "mongoid/extensions/string/inflections"
7
+ require "mongoid/extensions/symbol/inflections"
5
8
 
6
9
  class Array #:nodoc:
7
10
  include Mongoid::Extensions::Array::Conversions
8
11
  include Mongoid::Extensions::Array::Parentization
9
12
  end
10
13
 
14
+ class Hash #:nodoc
15
+ include Mongoid::Extensions::Hash::Accessors
16
+ end
17
+
11
18
  class Object #:nodoc:
12
19
  include Mongoid::Extensions::Object::Conversions
13
20
  include Mongoid::Extensions::Object::Parentization
14
- end
21
+ end
22
+
23
+ class String #:nodoc
24
+ include Mongoid::Extensions::String::Inflections
25
+ end
26
+
27
+ class Symbol #:nodoc
28
+ include Mongoid::Extensions::Symbol::Inflections
29
+ end
@@ -10,4 +10,4 @@ module Mongoid #:nodoc:
10
10
  end
11
11
  end
12
12
  end
13
- end
13
+ end
@@ -3,10 +3,10 @@ module Mongoid #:nodoc:
3
3
  module Array #:nodoc:
4
4
  module Parentization #:nodoc:
5
5
  # Adds the parent document to each element in the array.
6
- def parentize(parent)
7
- each { |obj| obj.parentize(parent) }
6
+ def parentize(parent, association_name)
7
+ each { |obj| obj.parentize(parent, association_name) }
8
8
  end
9
9
  end
10
10
  end
11
11
  end
12
- end
12
+ end
@@ -0,0 +1,21 @@
1
+ module Mongoid #:nodoc:
2
+ module Extensions #:nodoc:
3
+ module Hash #:nodoc:
4
+ module Accessors #:nodoc:
5
+ def insert(key, attrs)
6
+ # TODO: Refactor me.
7
+ store(key, attrs) if key.singular?
8
+ if key.plural?
9
+ if has_key?(key)
10
+ elements = fetch(key)
11
+ elements.delete_if { |e| (e[:_id] == attrs[:_id]) }
12
+ elements << attrs
13
+ else
14
+ store(key, [attrs])
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -3,10 +3,12 @@ module Mongoid #:nodoc:
3
3
  module Object #:nodoc:
4
4
  module Parentization #:nodoc:
5
5
  # Sets the parent object
6
- def parentize(object)
6
+ def parentize(object, association_name)
7
7
  self.parent = object
8
+ self.association_name = association_name
9
+ add_observer(object)
8
10
  end
9
11
  end
10
12
  end
11
13
  end
12
- end
14
+ end
@@ -0,0 +1,14 @@
1
+ module Mongoid #:nodoc:
2
+ module Extensions #:nodoc:
3
+ module String #:nodoc:
4
+ module Inflections #:nodoc:
5
+ def singular?
6
+ singularize == self
7
+ end
8
+ def plural?
9
+ pluralize == self
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module Mongoid #:nodoc:
2
+ module Extensions #:nodoc:
3
+ module Symbol #:nodoc:
4
+ module Inflections #:nodoc:
5
+ def singular?
6
+ to_s.singular?
7
+ end
8
+ def plural?
9
+ to_s.plural?
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,30 @@
1
+ module Mongoid
2
+ module Timestamps
3
+
4
+ def self.included(base)
5
+ base.class_eval do
6
+ include InstanceMethods
7
+ field :created_at
8
+ field :modified_at
9
+ before_create :update_created_at, :update_modified_at
10
+ before_save :update_modified_at
11
+ end
12
+ end
13
+
14
+ module InstanceMethods
15
+
16
+ # Update the created_at field on the Document to the current time. This is
17
+ # only called on create.
18
+ def update_created_at
19
+ self.created_at = Time.now
20
+ end
21
+
22
+ # Update the last_modified field on the Document to the current time.
23
+ # This is only called on create and on save.
24
+ def update_modified_at
25
+ self.modified_at = Time.now
26
+ end
27
+ end
28
+
29
+ end
30
+ end
data/mongoid.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{mongoid}
8
- s.version = "0.4.5"
8
+ s.version = "0.4.7"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Durran Jordan"]
12
- s.date = %q{2009-10-18}
12
+ s.date = %q{2009-10-25}
13
13
  s.email = %q{durran@gmail.com}
14
14
  s.extra_rdoc_files = [
15
15
  "README.textile"
@@ -40,9 +40,13 @@ Gem::Specification.new do |s|
40
40
  "lib/mongoid/extensions.rb",
41
41
  "lib/mongoid/extensions/array/conversions.rb",
42
42
  "lib/mongoid/extensions/array/parentization.rb",
43
+ "lib/mongoid/extensions/hash/accessors.rb",
43
44
  "lib/mongoid/extensions/object/conversions.rb",
44
45
  "lib/mongoid/extensions/object/parentization.rb",
46
+ "lib/mongoid/extensions/string/inflections.rb",
47
+ "lib/mongoid/extensions/symbol/inflections.rb",
45
48
  "lib/mongoid/field.rb",
49
+ "lib/mongoid/timestamps.rb",
46
50
  "mongoid.gemspec",
47
51
  "spec/integration/mongoid/document_spec.rb",
48
52
  "spec/spec.opts",
@@ -52,6 +56,7 @@ Gem::Specification.new do |s|
52
56
  "spec/unit/mongoid/associations/factory_spec.rb",
53
57
  "spec/unit/mongoid/associations/has_many_association_spec.rb",
54
58
  "spec/unit/mongoid/associations/has_one_association_spec.rb",
59
+ "spec/unit/mongoid/associations_spec.rb",
55
60
  "spec/unit/mongoid/commands/create_spec.rb",
56
61
  "spec/unit/mongoid/commands/delete_all_spec.rb",
57
62
  "spec/unit/mongoid/commands/delete_spec.rb",
@@ -63,9 +68,13 @@ Gem::Specification.new do |s|
63
68
  "spec/unit/mongoid/document_spec.rb",
64
69
  "spec/unit/mongoid/extensions/array/conversions_spec.rb",
65
70
  "spec/unit/mongoid/extensions/array/parentization_spec.rb",
71
+ "spec/unit/mongoid/extensions/hash/accessors_spec.rb",
66
72
  "spec/unit/mongoid/extensions/object/conversions_spec.rb",
67
73
  "spec/unit/mongoid/extensions/object/parentization_spec.rb",
68
- "spec/unit/mongoid/field_spec.rb"
74
+ "spec/unit/mongoid/extensions/string/inflections_spec.rb",
75
+ "spec/unit/mongoid/extensions/symbol/inflections_spec.rb",
76
+ "spec/unit/mongoid/field_spec.rb",
77
+ "spec/unit/mongoid/timestamps_spec.rb"
69
78
  ]
70
79
  s.homepage = %q{http://github.com/durran/mongoid}
71
80
  s.rdoc_options = ["--charset=UTF-8"]
@@ -80,6 +89,7 @@ Gem::Specification.new do |s|
80
89
  "spec/unit/mongoid/associations/factory_spec.rb",
81
90
  "spec/unit/mongoid/associations/has_many_association_spec.rb",
82
91
  "spec/unit/mongoid/associations/has_one_association_spec.rb",
92
+ "spec/unit/mongoid/associations_spec.rb",
83
93
  "spec/unit/mongoid/commands/create_spec.rb",
84
94
  "spec/unit/mongoid/commands/delete_all_spec.rb",
85
95
  "spec/unit/mongoid/commands/delete_spec.rb",
@@ -91,9 +101,13 @@ Gem::Specification.new do |s|
91
101
  "spec/unit/mongoid/document_spec.rb",
92
102
  "spec/unit/mongoid/extensions/array/conversions_spec.rb",
93
103
  "spec/unit/mongoid/extensions/array/parentization_spec.rb",
104
+ "spec/unit/mongoid/extensions/hash/accessors_spec.rb",
94
105
  "spec/unit/mongoid/extensions/object/conversions_spec.rb",
95
106
  "spec/unit/mongoid/extensions/object/parentization_spec.rb",
96
- "spec/unit/mongoid/field_spec.rb"
107
+ "spec/unit/mongoid/extensions/string/inflections_spec.rb",
108
+ "spec/unit/mongoid/extensions/symbol/inflections_spec.rb",
109
+ "spec/unit/mongoid/field_spec.rb",
110
+ "spec/unit/mongoid/timestamps_spec.rb"
97
111
  ]
98
112
 
99
113
  if s.respond_to? :specification_version then
@@ -60,7 +60,7 @@ describe Mongoid::Document do
60
60
 
61
61
  end
62
62
 
63
- describe "#group_by" do
63
+ describe "#group" do
64
64
 
65
65
  before do
66
66
  30.times do |num|
@@ -69,7 +69,7 @@ describe Mongoid::Document do
69
69
  end
70
70
 
71
71
  it "returns grouped documents" do
72
- grouped = Person.group_by([:title], {})
72
+ grouped = Person.select(:title).group
73
73
  people = grouped.first["group"]
74
74
  person = people.first
75
75
  person.should be_a_kind_of(Person)
data/spec/spec_helper.rb CHANGED
@@ -16,6 +16,7 @@ Spec::Runner.configure do |config|
16
16
  end
17
17
 
18
18
  class Person < Mongoid::Document
19
+ include Mongoid::Timestamps
19
20
  field :title
20
21
  field :terms
21
22
  field :age
@@ -37,10 +38,6 @@ class Name < Mongoid::Document
37
38
  belongs_to :person
38
39
  end
39
40
 
40
- class Tester < Mongoid::Document
41
- has_timestamps
42
- end
43
-
44
41
  class Decorated
45
42
  include Mongoid::Associations::Decorator
46
43
 
@@ -8,7 +8,7 @@ describe Mongoid::Associations::HasManyAssociation do
8
8
  @attributes = { :addresses => [
9
9
  { :_id => @first_id, :street => "Street 1" },
10
10
  { :_id => @second_id, :street => "Street 2" } ] }
11
- @document = stub(:attributes => @attributes)
11
+ @document = stub(:attributes => @attributes, :add_observer => true, :update => true)
12
12
  end
13
13
 
14
14
  describe "#[]" do
@@ -0,0 +1,125 @@
1
+ require File.join(File.dirname(__FILE__), "/../../spec_helper.rb")
2
+
3
+ describe Mongoid::Associations do
4
+
5
+ before do
6
+ @collection = stub(:name => "people")
7
+ @database = stub(:collection => @collection)
8
+ Mongoid.stubs(:database).returns(@database)
9
+ end
10
+
11
+ after do
12
+ Person.instance_variable_set(:@collection, nil)
13
+ @database = nil
14
+ @collection = nil
15
+ end
16
+
17
+ describe "#association=" do
18
+
19
+ context "when child is a has one" do
20
+
21
+ before do
22
+ @person = Person.new(:title => "Sir", :age => 30)
23
+ @name = Name.new(:first_name => "Test", :last_name => "User")
24
+ @person.name = @name
25
+ end
26
+
27
+ it "parentizes the association" do
28
+ @name.parent.should == @person
29
+ end
30
+
31
+ it "sets the child attributes on the parent" do
32
+ @person.attributes[:name].should == { :first_name => "Test", :last_name => "User" }
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+
39
+ describe "#belongs_to" do
40
+
41
+ it "creates a reader for the association" do
42
+ address = Address.new
43
+ address.should respond_to(:person)
44
+ end
45
+
46
+ it "creates a writer for the association" do
47
+ address = Address.new
48
+ address.should respond_to(:person=)
49
+ end
50
+
51
+ end
52
+
53
+ describe "#has_many" do
54
+
55
+ it "adds a new Association to the collection" do
56
+ person = Person.new
57
+ person.addresses.should_not be_nil
58
+ end
59
+
60
+ it "creates a reader for the association" do
61
+ person = Person.new
62
+ person.should respond_to(:addresses)
63
+ end
64
+
65
+ it "creates a writer for the association" do
66
+ person = Person.new
67
+ person.should respond_to(:addresses=)
68
+ end
69
+
70
+ context "when setting the association directly" do
71
+
72
+ before do
73
+ @attributes = { :title => "Sir",
74
+ :addresses => [
75
+ { :street => "Street 1" },
76
+ { :street => "Street 2" } ] }
77
+ @person = Person.new(@attributes)
78
+ end
79
+
80
+ it "sets the attributes for the association" do
81
+ address = Address.new(:street => "New Street")
82
+ @person.addresses = [address]
83
+ @person.addresses.first.street.should == "New Street"
84
+ end
85
+
86
+ end
87
+
88
+ end
89
+
90
+ describe "#has_one" do
91
+
92
+ it "adds a new Association to the collection" do
93
+ person = Person.new
94
+ person.name.should_not be_nil
95
+ end
96
+
97
+ it "creates a reader for the association" do
98
+ person = Person.new
99
+ person.should respond_to(:name)
100
+ end
101
+
102
+ it "creates a writer for the association" do
103
+ person = Person.new
104
+ person.should respond_to(:name=)
105
+ end
106
+
107
+ context "when setting the association directly" do
108
+
109
+ before do
110
+ @attributes = { :title => "Sir",
111
+ :name => { :first_name => "Test" } }
112
+ @person = Person.new(@attributes)
113
+ end
114
+
115
+ it "sets the attributes for the association" do
116
+ name = Name.new(:first_name => "New Name")
117
+ @person.name = name
118
+ @person.name.first_name.should == "New Name"
119
+ end
120
+
121
+ end
122
+
123
+ end
124
+
125
+ end
@@ -6,6 +6,41 @@ describe Mongoid::Criteria do
6
6
  @criteria = Mongoid::Criteria.new(:all)
7
7
  end
8
8
 
9
+ describe "#aggregate" do
10
+
11
+ context "when klass provided" do
12
+
13
+ before do
14
+ @reduce = "function(obj, prev) { prev.count++; }"
15
+ @criteria = Mongoid::Criteria.new(:all, Person)
16
+ @collection = mock
17
+ Person.expects(:collection).returns(@collection)
18
+ end
19
+
20
+ it "calls group on the collection with the aggregate js" do
21
+ @collection.expects(:group).with([:field1], {}, {:count => 0}, @reduce)
22
+ @criteria.select(:field1).aggregate
23
+ end
24
+
25
+ end
26
+
27
+ context "when klass not provided" do
28
+
29
+ before do
30
+ @reduce = "function(obj, prev) { prev.count++; }"
31
+ @collection = mock
32
+ Person.expects(:collection).returns(@collection)
33
+ end
34
+
35
+ it "calls group on the collection with the aggregate js" do
36
+ @collection.expects(:group).with([:field1], {}, {:count => 0}, @reduce)
37
+ @criteria.select(:field1).aggregate(Person)
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+
9
44
  describe "#all" do
10
45
 
11
46
  it "adds the $all query to the selector" do
@@ -73,6 +108,45 @@ describe Mongoid::Criteria do
73
108
 
74
109
  end
75
110
 
111
+ describe "#group" do
112
+
113
+ before do
114
+ @grouping = [{ "title" => "Sir", "group" => [{ "title" => "Sir", "age" => 30 }] }]
115
+ end
116
+
117
+ context "when klass provided" do
118
+
119
+ before do
120
+ @reduce = "function(obj, prev) { prev.group.push(obj); }"
121
+ @criteria = Mongoid::Criteria.new(:all, Person)
122
+ @collection = mock
123
+ Person.expects(:collection).returns(@collection)
124
+ end
125
+
126
+ it "calls group on the collection with the aggregate js" do
127
+ @collection.expects(:group).with([:field1], {}, {:group => []}, @reduce).returns(@grouping)
128
+ @criteria.select(:field1).group
129
+ end
130
+
131
+ end
132
+
133
+ context "when klass not provided" do
134
+
135
+ before do
136
+ @reduce = "function(obj, prev) { prev.group.push(obj); }"
137
+ @collection = mock
138
+ Person.expects(:collection).returns(@collection)
139
+ end
140
+
141
+ it "calls group on the collection with the aggregate js" do
142
+ @collection.expects(:group).with([:field1], {}, {:group => []}, @reduce).returns(@grouping)
143
+ @criteria.select(:field1).group(Person)
144
+ end
145
+
146
+ end
147
+
148
+ end
149
+
76
150
  describe "#id" do
77
151
 
78
152
  it "adds the _id query to the selector" do
@@ -140,6 +214,53 @@ describe Mongoid::Criteria do
140
214
 
141
215
  end
142
216
 
217
+ describe "#offset" do
218
+
219
+ context "when the per_page option exists" do
220
+
221
+ before do
222
+ @criteria = Mongoid::Criteria.new(:all).extras({ :per_page => 20 })
223
+ end
224
+
225
+ it "returns the per_page option" do
226
+ @criteria.offset.should == 20
227
+ end
228
+
229
+ it "replaces per_page with skip in the options" do
230
+ @criteria.offset
231
+ @criteria.options[:per_page].should be_nil
232
+ @criteria.options[:skip].should == 20
233
+ end
234
+
235
+ end
236
+
237
+ context "when the skip option exists" do
238
+
239
+ before do
240
+ @criteria = Mongoid::Criteria.new(:all).extras({ :skip => 20 })
241
+ end
242
+
243
+ it "returns the skip option" do
244
+ @criteria.offset.should == 20
245
+ end
246
+
247
+ end
248
+
249
+ context "when no option exists" do
250
+
251
+ before do
252
+ @criteria = Mongoid::Criteria.new(:all)
253
+ end
254
+
255
+ it "adds the skip option to the options and returns it" do
256
+ @criteria.offset.should == 20
257
+ @criteria.options[:skip].should == 20
258
+ end
259
+
260
+ end
261
+
262
+ end
263
+
143
264
  describe "#order_by" do
144
265
 
145
266
  context "when field names and direction specified" do
@@ -157,6 +278,39 @@ describe Mongoid::Criteria do
157
278
 
158
279
  end
159
280
 
281
+ describe "#page" do
282
+
283
+ context "when the page option exists" do
284
+
285
+ before do
286
+ @criteria = Mongoid::Criteria.new(:all).extras({ :page => 5 })
287
+ end
288
+
289
+ it "returns the page option" do
290
+ @criteria.page.should == 5
291
+ end
292
+
293
+ it "deletes the page option from the options" do
294
+ @criteria.page.should == 5
295
+ @criteria.options[:page].should be_nil
296
+ end
297
+
298
+ end
299
+
300
+ context "when the page option does not exist" do
301
+
302
+ before do
303
+ @criteria = Mongoid::Criteria.new(:all)
304
+ end
305
+
306
+ it "returns 1" do
307
+ @criteria.page.should == 1
308
+ end
309
+
310
+ end
311
+
312
+ end
313
+
160
314
  describe "#select" do
161
315
 
162
316
  it "adds the options for limiting by fields" do