mongomodel 0.2.10 → 0.2.11

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/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
1
  source "http://rubygems.org"
2
2
 
3
3
  gemspec
4
- gem "bson_ext", '= 1.0.7'
4
+ gem "bson_ext", '= 1.1.2'
@@ -49,6 +49,7 @@ module MongoModel
49
49
  autoload :BeforeTypeCast, 'mongomodel/concerns/attribute_methods/before_type_cast'
50
50
  autoload :Protected, 'mongomodel/concerns/attribute_methods/protected'
51
51
  autoload :Dirty, 'mongomodel/concerns/attribute_methods/dirty'
52
+ autoload :MultiParameterAssignment, 'mongomodel/concerns/attribute_methods/multi_parameter_assignment'
52
53
  end
53
54
 
54
55
  module Attributes
@@ -11,7 +11,25 @@ module MongoModel
11
11
 
12
12
  def define!
13
13
  raise "has_many :by => :foreign_key is only valid on Document" unless owner.ancestors.include?(Document)
14
+
14
15
  super
16
+
17
+ define_dependency_callbacks!
18
+ self
19
+ end
20
+
21
+ def define_dependency_callbacks!
22
+ association = self
23
+
24
+ if options[:dependent] == :destroy
25
+ owner.before_destroy do
26
+ send(association.name).each { |child| child.destroy }
27
+ end
28
+ elsif options[:dependent] == :delete
29
+ owner.before_destroy do
30
+ send(association.name).delete_all
31
+ end
32
+ end
15
33
  end
16
34
 
17
35
  methods do |association|
@@ -5,6 +5,26 @@ module MongoModel
5
5
  :"#{singular_name}_ids"
6
6
  end
7
7
 
8
+ def define!
9
+ super
10
+ define_dependency_callbacks!
11
+ self
12
+ end
13
+
14
+ def define_dependency_callbacks!
15
+ association = self
16
+
17
+ if options[:dependent] == :destroy
18
+ owner.before_destroy do
19
+ send(association.name).each { |child| child.destroy }
20
+ end
21
+ elsif options[:dependent] == :delete
22
+ owner.before_destroy do
23
+ send(association.name).delete_all
24
+ end
25
+ end
26
+ end
27
+
8
28
  properties do |association|
9
29
  property association.property_name, Collection[MongoModel::Reference], :internal => true, :default => []
10
30
  end
@@ -0,0 +1,42 @@
1
+ module MongoModel
2
+ module AttributeMethods
3
+ module MultiParameterAssignment
4
+ extend ActiveSupport::Concern
5
+
6
+ def attributes=(attrs)#:nodoc:
7
+ super(transform_multiparameter_attributes(attrs))
8
+ end
9
+
10
+ private
11
+ # Converts multiparameter attributes into array format. For example, the parameters
12
+ # { "start_date(1i)" => "2010", "start_date(2i)" => "9", "start_date(3i)" => "4" }
13
+ # will be converted to:
14
+ # { "start_date" => [2010, 9, 4] }
15
+ def transform_multiparameter_attributes(attrs)
16
+ attrs.merge(extract_multiparameter_attributes(attrs))
17
+ end
18
+
19
+ def extract_multiparameter_attributes(attrs)
20
+ multiparameter_attributes = Hash.new { |h, k| h[k] = [] }
21
+
22
+ attrs.each do |k, v|
23
+ if k.to_s =~ /(.*)\((\d+)([if])?\)/
24
+ multiparameter_attributes[$1][$2.to_i - 1] = type_cast_attribute_value($3, v)
25
+ attrs.delete(k)
26
+ end
27
+ end
28
+
29
+ multiparameter_attributes
30
+ end
31
+
32
+ def type_cast_attribute_value(type, value)
33
+ case type
34
+ when 'i', 'f'
35
+ value.send("to_#{type}")
36
+ else
37
+ value
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,127 +1,24 @@
1
1
  module MongoModel
2
2
  module AttributeMethods
3
3
  module Protected
4
- extend ActiveSupport::Concern
5
-
6
- module ClassMethods
7
- def property(name, *args, &block)#:nodoc:
8
- property = super(name, *args, &block)
9
-
10
- attr_protected(name) if property.options[:protected]
11
- attr_accessible(name) if property.options[:accessible]
12
-
13
- property
14
- end
15
-
16
- # Attributes named in this macro are protected from mass-assignment,
17
- # such as <tt>new(attributes)</tt>,
18
- # <tt>update_attributes(attributes)</tt>, or
19
- # <tt>attributes=(attributes)</tt>.
20
- #
21
- # Mass-assignment to these attributes will simply be ignored, to assign
22
- # to them you can use direct writer methods. This is meant to protect
23
- # sensitive attributes from being overwritten by malicious users
24
- # tampering with URLs or forms.
25
- #
26
- # class Customer < Recliner::Document
27
- # attr_protected :credit_rating
28
- # end
29
- #
30
- # customer = Customer.new("name" => David, "credit_rating" => "Excellent")
31
- # customer.credit_rating # => nil
32
- # customer.attributes = { "description" => "Jolly fellow", "credit_rating" => "Superb" }
33
- # customer.credit_rating # => nil
34
- #
35
- # customer.credit_rating = "Average"
36
- # customer.credit_rating # => "Average"
37
- #
38
- # To start from an all-closed default and enable attributes as needed,
39
- # have a look at +attr_accessible+.
40
- #
41
- # If the access logic of your application is richer you can use <tt>Hash#except</tt>
42
- # or <tt>Hash#slice</tt> to sanitize the hash of parameters before they are
43
- # passed to Recliner.
44
- #
45
- # For example, it could be the case that the list of protected attributes
46
- # for a given model depends on the role of the user:
47
- #
48
- # # Assumes plan_id is not protected because it depends on the role.
49
- # params[:account] = params[:account].except(:plan_id) unless admin?
50
- # @account.update_attributes(params[:account])
51
- #
52
- # Note that +attr_protected+ is still applied to the received hash. Thus,
53
- # with this technique you can at most _extend_ the list of protected
54
- # attributes for a particular mass-assignment call.
55
- def attr_protected(*attrs)
56
- write_inheritable_attribute(:attr_protected, attrs.map { |a| a.to_s } + protected_attributes)
57
- end
58
-
59
- # Specifies a white list of model attributes that can be set via
60
- # mass-assignment, such as <tt>new(attributes)</tt>,
61
- # <tt>update_attributes(attributes)</tt>, or
62
- # <tt>attributes=(attributes)</tt>
63
- #
64
- # This is the opposite of the +attr_protected+ macro: Mass-assignment
65
- # will only set attributes in this list, to assign to the rest of
66
- # attributes you can use direct writer methods. This is meant to protect
67
- # sensitive attributes from being overwritten by malicious users
68
- # tampering with URLs or forms. If you'd rather start from an all-open
69
- # default and restrict attributes as needed, have a look at
70
- # +attr_protected+.
71
- #
72
- # class Customer < Recliner::Document
73
- # attr_accessible :name, :nickname
74
- # end
75
- #
76
- # customer = Customer.new(:name => "David", :nickname => "Dave", :credit_rating => "Excellent")
77
- # customer.credit_rating # => nil
78
- # customer.attributes = { :name => "Jolly fellow", :credit_rating => "Superb" }
79
- # customer.credit_rating # => nil
80
- #
81
- # customer.credit_rating = "Average"
82
- # customer.credit_rating # => "Average"
83
- #
84
- # If the access logic of your application is richer you can use <tt>Hash#except</tt>
85
- # or <tt>Hash#slice</tt> to sanitize the hash of parameters before they are
86
- # passed to Recliner.
87
- #
88
- # For example, it could be the case that the list of accessible attributes
89
- # for a given model depends on the role of the user:
90
- #
91
- # # Assumes plan_id is accessible because it depends on the role.
92
- # params[:account] = params[:account].except(:plan_id) unless admin?
93
- # @account.update_attributes(params[:account])
94
- #
95
- # Note that +attr_accessible+ is still applied to the received hash. Thus,
96
- # with this technique you can at most _narrow_ the list of accessible
97
- # attributes for a particular mass-assignment call.
98
- def attr_accessible(*attrs)
99
- write_inheritable_attribute(:attr_accessible, attrs.map { |a| a.to_s } + accessible_attributes)
100
- end
101
-
102
- # Returns an array of all the attributes that have been protected from mass-assignment.
103
- def protected_attributes
104
- read_inheritable_attribute(:attr_protected) || []
105
- end
106
-
107
- # Returns an array of all the attributes that have been made accessible to mass-assignment.
108
- def accessible_attributes
109
- read_inheritable_attribute(:attr_accessible) || []
110
- end
111
- end
112
-
113
- def attributes=(attrs)#:nodoc:
114
- super(remove_protected_attributes(attrs))
115
- end
116
-
117
- private
118
- def remove_protected_attributes(attrs)
119
- if self.class.accessible_attributes.empty?
120
- attrs.reject { |k, v| self.class.protected_attributes.include?(k.to_s) }
121
- else
122
- attrs.reject { |k, v| !self.class.accessible_attributes.include?(k.to_s) }
123
- end
4
+ extend ActiveSupport::Concern
5
+
6
+ include ActiveModel::MassAssignmentSecurity
7
+
8
+ module ClassMethods
9
+ def property(name, *args, &block)#:nodoc:
10
+ property = super(name, *args, &block)
11
+
12
+ attr_protected(name) if property.options[:protected]
13
+ attr_accessible(name) if property.options[:accessible]
14
+
15
+ property
124
16
  end
17
+ end
18
+
19
+ def attributes=(attrs)#:nodoc:
20
+ super(sanitize_for_mass_assignment(attrs))
21
+ end
125
22
  end
126
23
  end
127
24
  end
@@ -45,7 +45,10 @@ module MongoModel
45
45
  class Index
46
46
  def initialize(*keys)
47
47
  options = keys.extract_options!
48
+
48
49
  @unique = options.delete(:unique)
50
+ @min = options.delete(:min)
51
+ @max = options.delete(:max)
49
52
 
50
53
  keys.each do |key|
51
54
  self.keys[key.to_sym] = :ascending
@@ -64,16 +67,26 @@ module MongoModel
64
67
  @unique
65
68
  end
66
69
 
70
+ def geo2d?
71
+ @geo2d ||= keys.size == 1 && keys.values.first == :geo2d
72
+ end
73
+
67
74
  def to_args
68
75
  args = []
69
76
 
70
- if keys.size == 1 && keys.all? { |k, o| o == :ascending }
77
+ if geo2d?
78
+ args << [[keys.keys.first, Mongo::GEO2D]]
79
+ elsif keys.size == 1 && keys.values.first == :ascending
71
80
  args << keys.keys.first
72
81
  else
73
- args << keys.map { |k, o| [k, o == :ascending ? 1 : -1] }.sort_by { |k| k.first.to_s }
82
+ args << keys.map { |k, o| [k, o == :ascending ? Mongo::ASCENDING : Mongo::DESCENDING] }.sort_by { |k| k.first.to_s }
83
+ end
84
+
85
+ if geo2d? && @min && @max
86
+ args << { :min => @min, :max => @max }
87
+ elsif unique?
88
+ args << { :unique => true }
74
89
  end
75
-
76
- args << { :unique => true } if unique?
77
90
 
78
91
  args
79
92
  end
@@ -98,6 +98,14 @@ module MongoModel
98
98
  superclass.collection_name
99
99
  end
100
100
  end
101
+
102
+ def use_type_selector?
103
+ !superclass.abstract_class?
104
+ end
105
+
106
+ def type_selector
107
+ [self.to_s] + descendants.map { |m| m.to_s }
108
+ end
101
109
 
102
110
  def collection
103
111
  @_collection ||= database.collection(collection_name)
@@ -20,6 +20,7 @@ module MongoModel
20
20
  include AttributeMethods::BeforeTypeCast
21
21
  include AttributeMethods::Protected
22
22
  include AttributeMethods::Dirty
23
+ include AttributeMethods::MultiParameterAssignment
23
24
 
24
25
  include Logging
25
26
  include RecordStatus
@@ -1,7 +1,7 @@
1
1
  class Boolean < TrueClass; end
2
2
 
3
3
  class Symbol
4
- [:lt, :lte, :gt, :gte, :ne, :in, :nin, :mod, :all, :size, :exists].each do |operator|
4
+ [:lt, :lte, :gt, :gte, :ne, :in, :nin, :mod, :all, :size, :exists, :near].each do |operator|
5
5
  define_method(operator) { MongoModel::MongoOperator.new(self, operator) }
6
6
  end
7
7
 
@@ -70,8 +70,8 @@ module MongoModel
70
70
  end
71
71
 
72
72
  def add_type_to_selector
73
- unless selector['_type'] || @model.superclass.abstract_class?
74
- selector['_type'] = { '$in' => [@model.to_s] + @model.subclasses.map { |m| m.to_s } }
73
+ if @model.use_type_selector? && selector['_type'].nil?
74
+ selector['_type'] = { '$in' => @model.type_selector }
75
75
  end
76
76
  end
77
77
  end
@@ -5,7 +5,14 @@ module MongoModel
5
5
  module Types
6
6
  class Date < Object
7
7
  def cast(value)
8
- value.to_date rescue nil
8
+ case value
9
+ when ::Array
10
+ ::Date.new(*value)
11
+ else
12
+ value.to_date
13
+ end
14
+ rescue
15
+ nil
9
16
  end
10
17
 
11
18
  def to_mongo(value)
@@ -5,8 +5,14 @@ module MongoModel
5
5
  module Types
6
6
  class Time < Object
7
7
  def cast(value)
8
- time = value.to_time
9
- time.change(:usec => (time.usec / 1000.0).floor * 1000)
8
+ case value
9
+ when ::Array
10
+ base = ::Time.zone ? ::Time.zone : ::Time
11
+ base.local(*value)
12
+ else
13
+ time = value.to_time
14
+ time.change(:usec => (time.usec / 1000.0).floor * 1000)
15
+ end
10
16
  rescue
11
17
  nil
12
18
  end
@@ -1,3 +1,3 @@
1
1
  module MongoModel
2
- VERSION = "0.2.10"
2
+ VERSION = "0.2.11"
3
3
  end
@@ -14,12 +14,12 @@ Gem::Specification.new do |s|
14
14
  s.required_rubygems_version = ">= 1.3.6"
15
15
  s.rubyforge_project = "mongomodel"
16
16
 
17
- s.add_dependency "activesupport", "~> 3.0.0"
18
- s.add_dependency "activemodel", "~> 3.0.0"
19
- s.add_dependency "mongo", "~> 1.0.7"
17
+ s.add_dependency "activesupport", "~> 3.0.3"
18
+ s.add_dependency "activemodel", "~> 3.0.3"
19
+ s.add_dependency "mongo", "~> 1.1.2"
20
20
 
21
21
  s.add_development_dependency "bundler", ">= 1.0.0"
22
- s.add_development_dependency "rspec", "= 1.3.0"
22
+ s.add_development_dependency "rspec", "= 1.3.0"
23
23
 
24
24
  s.files = `git ls-files`.split("\n")
25
25
  s.require_path = 'lib'
@@ -39,10 +39,17 @@ module MongoModel
39
39
  it { should respond_to(:to_param) }
40
40
 
41
41
  specify "to_param should return nil if subject.persisted? is false" do
42
+ subject.stub!(:to_key).and_return([1])
42
43
  subject.stub!(:persisted?).and_return(false)
43
44
  subject.to_param.should be_nil
44
45
  end
45
46
 
47
+ # == Responds to <tt>valid?</tt>
48
+ #
49
+ # Returns a boolean that specifies whether the object is in a valid or invalid
50
+ # state.
51
+ it { should respond_to_boolean(:valid?) }
52
+
46
53
  # == Responds to <tt>persisted?</tt>
47
54
  #
48
55
  # Returns a boolean that specifies whether the object has been persisted yet.
@@ -70,26 +77,6 @@ module MongoModel
70
77
  model_name.plural.should be_a_kind_of(String)
71
78
  end
72
79
 
73
- # ## Old
74
- #
75
- # # valid?
76
- # # ------
77
- # #
78
- # # Returns a boolean that specifies whether the object is in a valid or invalid
79
- # # state.
80
- # it { should respond_to_boolean(:valid?) }
81
- #
82
- # # new_record?
83
- # # -----------
84
- # #
85
- # # Returns a boolean that specifies whether the object has been persisted yet.
86
- # # This is used when calculating the URL for an object. If the object is
87
- # # not persisted, a form for that object, for instance, will be POSTed to the
88
- # # collection. If it is persisted, a form for the object will put PUTed to the
89
- # # URL for the object.
90
- # it { should respond_to_boolean(:new_record?) }
91
- # it { should respond_to_boolean(:destroyed?) }
92
-
93
80
  # == Errors Testing
94
81
  #
95
82
  # Returns an object that has :[] and :full_messages defined on it. See below
@@ -168,6 +168,58 @@ module MongoModel
168
168
  subject { Book.find(book.id) }
169
169
  it_should_behave_like "accessing and manipulating a has_many :by => :foreign_key association"
170
170
  end
171
+
172
+ describe "with :dependent => :destroy option" do
173
+ define_class(:Book, Document) do
174
+ has_many :chapters, :by => :foreign_key, :dependent => :destroy
175
+ end
176
+
177
+ subject { Book.create!(:chapters => [chapter1, chapter2, chapter3]) }
178
+
179
+ context "when the parent object is destroyed" do
180
+ it "should call destroy on the child objects" do
181
+ chapter1.should_receive(:destroy)
182
+ chapter2.should_receive(:destroy)
183
+ chapter3.should_receive(:destroy)
184
+
185
+ subject.destroy
186
+ end
187
+
188
+ it "should remove the child objects from their collection" do
189
+ subject.destroy
190
+
191
+ Chapter.exists?(chapter1.id).should be_false
192
+ Chapter.exists?(chapter2.id).should be_false
193
+ Chapter.exists?(chapter3.id).should be_false
194
+ end
195
+ end
196
+ end
197
+
198
+ describe "with :dependent => :delete option" do
199
+ define_class(:Book, Document) do
200
+ has_many :chapters, :by => :foreign_key, :dependent => :delete
201
+ end
202
+
203
+ subject { Book.create!(:chapters => [chapter1, chapter2, chapter3]) }
204
+
205
+ context "when the parent object is destroyed" do
206
+ it "should not call destroy on the child objects" do
207
+ chapter1.should_not_receive(:destroy)
208
+ chapter2.should_not_receive(:destroy)
209
+ chapter3.should_not_receive(:destroy)
210
+
211
+ subject.destroy
212
+ end
213
+
214
+ it "should remove the child objects from their collection" do
215
+ subject.destroy
216
+
217
+ Chapter.exists?(chapter1.id).should be_false
218
+ Chapter.exists?(chapter2.id).should be_false
219
+ Chapter.exists?(chapter3.id).should be_false
220
+ end
221
+ end
222
+ end
171
223
  end
172
224
  end
173
225
 
@@ -187,6 +187,74 @@ module MongoModel
187
187
 
188
188
  it_should_behave_like "accessing and manipulating a has_many :by => :ids association"
189
189
  end
190
+
191
+ describe "with :dependent => :destroy option" do
192
+ define_class(:Book, described_class) do
193
+ has_many :chapters, :by => :ids, :dependent => :destroy
194
+ end
195
+
196
+ if specing?(Document)
197
+ subject { Book.create!(:chapters => [chapter1, chapter2, chapter3]) }
198
+ else
199
+ define_class(:Bookshelf, Document) do
200
+ property :book, Book
201
+ end
202
+ let(:book) { Book.new(:chapters => [chapter1, chapter2, chapter3]) }
203
+ subject { Bookshelf.create!(:book => book) }
204
+ end
205
+
206
+ context "when the parent object is destroyed" do
207
+ it "should call destroy on the child objects" do
208
+ chapter1.should_receive(:destroy)
209
+ chapter2.should_receive(:destroy)
210
+ chapter3.should_receive(:destroy)
211
+
212
+ subject.destroy
213
+ end
214
+
215
+ it "should remove the child objects from their collection" do
216
+ subject.destroy
217
+
218
+ Chapter.exists?(chapter1.id).should be_false
219
+ Chapter.exists?(chapter2.id).should be_false
220
+ Chapter.exists?(chapter3.id).should be_false
221
+ end
222
+ end
223
+ end
224
+
225
+ describe "with :dependent => :delete option" do
226
+ define_class(:Book, described_class) do
227
+ has_many :chapters, :by => :ids, :dependent => :delete
228
+ end
229
+
230
+ if specing?(Document)
231
+ subject { Book.create!(:chapters => [chapter1, chapter2, chapter3]) }
232
+ else
233
+ define_class(:Bookshelf, Document) do
234
+ property :book, Book
235
+ end
236
+ let(:book) { Book.new(:chapters => [chapter1, chapter2, chapter3]) }
237
+ subject { Bookshelf.create!(:book => book) }
238
+ end
239
+
240
+ context "when the parent object is destroyed" do
241
+ it "should not call destroy on the child objects" do
242
+ chapter1.should_not_receive(:destroy)
243
+ chapter2.should_not_receive(:destroy)
244
+ chapter3.should_not_receive(:destroy)
245
+
246
+ subject.destroy
247
+ end
248
+
249
+ it "should remove the child objects from their collection" do
250
+ subject.destroy
251
+
252
+ Chapter.exists?(chapter1.id).should be_false
253
+ Chapter.exists?(chapter2.id).should be_false
254
+ Chapter.exists?(chapter3.id).should be_false
255
+ end
256
+ end
257
+ end
190
258
  end
191
259
  end
192
260
  end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ module MongoModel
4
+ specs_for(Document, EmbeddedDocument) do
5
+ define_class(:TestDocument, described_class) do
6
+ property :timestamp, Time
7
+ property :datestamp, Date
8
+ end
9
+
10
+ subject { TestDocument.new }
11
+
12
+ describe "multiparameter assignment" do
13
+ context "setting a timestamp" do
14
+ it "should combine and assign parameters as Time" do
15
+ subject.attributes = {
16
+ "timestamp(1i)" => "2009",
17
+ "timestamp(2i)" => "10",
18
+ "timestamp(3i)" => "5",
19
+ "timestamp(4i)" => "14",
20
+ "timestamp(5i)" => "35"
21
+ }
22
+
23
+ subject.timestamp.should == Time.local(2009, 10, 5, 14, 35)
24
+ end
25
+ end
26
+
27
+ context "setting a datestamp" do
28
+ it "should combine and assign parameters as Date" do
29
+ subject.attributes = {
30
+ "datestamp(1i)" => "2008",
31
+ "datestamp(2i)" => "4",
32
+ "datestamp(3i)" => "9"
33
+ }
34
+
35
+ subject.datestamp.should == Date.new(2008, 4, 9)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -6,6 +6,7 @@ module MongoModel
6
6
  define_class(:Article, Document) do
7
7
  property :title, String
8
8
  property :age, Integer
9
+ property :position, Array
9
10
  end
10
11
 
11
12
  def subclass(klass)
@@ -41,12 +42,14 @@ module MongoModel
41
42
  before(:each) do
42
43
  Article.index :title, :unique => true
43
44
  Article.index :age => :descending
45
+ Article.index :position => :geo2d, :min => -100, :max => 100
44
46
  end
45
47
 
46
48
  it "should create indexes on the collection" do
47
49
  Article.collection.should_receive(:create_index).with(:_type)
48
50
  Article.collection.should_receive(:create_index).with(:title, :unique => true)
49
51
  Article.collection.should_receive(:create_index).with([[:age, Mongo::DESCENDING]])
52
+ Article.collection.should_receive(:create_index).with([[:position, Mongo::GEO2D]], :min => -100, :max => 100)
50
53
  Article.ensure_indexes!
51
54
  end
52
55
 
@@ -108,6 +111,14 @@ module MongoModel
108
111
  Index.new(:title => :ascending, :age => :descending).to_args.should == [[[:age, Mongo::DESCENDING], [:title, Mongo::ASCENDING]]]
109
112
  end
110
113
 
114
+ it "should convert geospatial index with no options" do
115
+ Index.new(:position => :geo2d).to_args.should == [[[:position, Mongo::GEO2D]]]
116
+ end
117
+
118
+ it "should convert geospatial index with min/max options" do
119
+ Index.new(:position => :geo2d, :min => -50, :max => 50).to_args.should == [[[:position, Mongo::GEO2D]], { :min => -50, :max => 50 }]
120
+ end
121
+
111
122
  it "should be equal to an equivalent index" do
112
123
  Index.new(:title).should == Index.new(:title)
113
124
  Index.new(:title, :age).should == Index.new(:title => :ascending, :age => :ascending)
@@ -17,6 +17,7 @@ module MongoModel
17
17
  define_class(:Event, Document)
18
18
  define_class(:SpecialEvent, :Event)
19
19
  define_class(:VerySpecialEvent, :SpecialEvent)
20
+ define_class(:SuperSpecialEvent, :VerySpecialEvent)
20
21
 
21
22
  let(:missing) do
22
23
  e = Event.new
@@ -29,6 +30,7 @@ module MongoModel
29
30
  @event = Event.create!
30
31
  @special = SpecialEvent.create!
31
32
  @very_special = VerySpecialEvent.create!
33
+ @super_special = SuperSpecialEvent.create!
32
34
  @missing = missing
33
35
  end
34
36
 
@@ -59,14 +61,17 @@ module MongoModel
59
61
 
60
62
  describe "loading documents" do
61
63
  it "should load all documents from root class" do
62
- Event.all.should include(@event, @special, @very_special, @missing)
64
+ Event.all.should include(@event, @special, @very_special, @super_special, @missing)
63
65
  end
64
66
 
65
67
  it "should only load subclass documents from subclass" do
66
- SpecialEvent.all.should include(@special, @very_special)
68
+ SpecialEvent.all.should include(@special, @very_special, @super_special)
67
69
  SpecialEvent.all.should_not include(@event, @missing)
68
70
 
69
- VerySpecialEvent.all.should == [@very_special]
71
+ VerySpecialEvent.all.should include(@very_special, @super_special)
72
+ VerySpecialEvent.all.should_not include(@event, @special, @missing)
73
+
74
+ SuperSpecialEvent.all.should == [@super_special]
70
75
  end
71
76
  end
72
77
  end
@@ -20,6 +20,7 @@ module MongoModel
20
20
  it "should be created from symbol methods" do
21
21
  :age.gt.should == MongoOperator.new(:age, :gt)
22
22
  :date.lte.should == MongoOperator.new(:date, :lte)
23
+ :position.near.should == MongoOperator.new(:position, :near)
23
24
  end
24
25
 
25
26
  it "should be equal within a hash" do
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongomodel
3
3
  version: !ruby/object:Gem::Version
4
- hash: 3
5
4
  prerelease: false
6
5
  segments:
7
6
  - 0
8
7
  - 2
9
- - 10
10
- version: 0.2.10
8
+ - 11
9
+ version: 0.2.11
11
10
  platform: ruby
12
11
  authors:
13
12
  - Sam Pohlenz
@@ -15,7 +14,7 @@ autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2010-10-23 00:00:00 +10:30
17
+ date: 2010-11-22 00:00:00 +10:30
19
18
  default_executable:
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
@@ -26,12 +25,11 @@ dependencies:
26
25
  requirements:
27
26
  - - ~>
28
27
  - !ruby/object:Gem::Version
29
- hash: 7
30
28
  segments:
31
29
  - 3
32
30
  - 0
33
- - 0
34
- version: 3.0.0
31
+ - 3
32
+ version: 3.0.3
35
33
  type: :runtime
36
34
  version_requirements: *id001
37
35
  - !ruby/object:Gem::Dependency
@@ -42,12 +40,11 @@ dependencies:
42
40
  requirements:
43
41
  - - ~>
44
42
  - !ruby/object:Gem::Version
45
- hash: 7
46
43
  segments:
47
44
  - 3
48
45
  - 0
49
- - 0
50
- version: 3.0.0
46
+ - 3
47
+ version: 3.0.3
51
48
  type: :runtime
52
49
  version_requirements: *id002
53
50
  - !ruby/object:Gem::Dependency
@@ -58,12 +55,11 @@ dependencies:
58
55
  requirements:
59
56
  - - ~>
60
57
  - !ruby/object:Gem::Version
61
- hash: 25
62
58
  segments:
63
59
  - 1
64
- - 0
65
- - 7
66
- version: 1.0.7
60
+ - 1
61
+ - 2
62
+ version: 1.1.2
67
63
  type: :runtime
68
64
  version_requirements: *id003
69
65
  - !ruby/object:Gem::Dependency
@@ -74,7 +70,6 @@ dependencies:
74
70
  requirements:
75
71
  - - ">="
76
72
  - !ruby/object:Gem::Version
77
- hash: 23
78
73
  segments:
79
74
  - 1
80
75
  - 0
@@ -90,7 +85,6 @@ dependencies:
90
85
  requirements:
91
86
  - - "="
92
87
  - !ruby/object:Gem::Version
93
- hash: 27
94
88
  segments:
95
89
  - 1
96
90
  - 3
@@ -132,6 +126,7 @@ files:
132
126
  - lib/mongomodel/concerns/attribute_methods.rb
133
127
  - lib/mongomodel/concerns/attribute_methods/before_type_cast.rb
134
128
  - lib/mongomodel/concerns/attribute_methods/dirty.rb
129
+ - lib/mongomodel/concerns/attribute_methods/multi_parameter_assignment.rb
135
130
  - lib/mongomodel/concerns/attribute_methods/protected.rb
136
131
  - lib/mongomodel/concerns/attribute_methods/query.rb
137
132
  - lib/mongomodel/concerns/attribute_methods/read.rb
@@ -202,6 +197,7 @@ files:
202
197
  - spec/mongomodel/concerns/associations/has_many_by_ids_spec.rb
203
198
  - spec/mongomodel/concerns/attribute_methods/before_type_cast_spec.rb
204
199
  - spec/mongomodel/concerns/attribute_methods/dirty_spec.rb
200
+ - spec/mongomodel/concerns/attribute_methods/multi_parameter_assignment_spec.rb
205
201
  - spec/mongomodel/concerns/attribute_methods/protected_spec.rb
206
202
  - spec/mongomodel/concerns/attribute_methods/query_spec.rb
207
203
  - spec/mongomodel/concerns/attribute_methods/read_spec.rb
@@ -261,7 +257,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
261
257
  requirements:
262
258
  - - ">="
263
259
  - !ruby/object:Gem::Version
264
- hash: 3
265
260
  segments:
266
261
  - 0
267
262
  version: "0"
@@ -270,7 +265,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
270
265
  requirements:
271
266
  - - ">="
272
267
  - !ruby/object:Gem::Version
273
- hash: 23
274
268
  segments:
275
269
  - 1
276
270
  - 3