mongomodel 0.2.10 → 0.2.11

Sign up to get free protection for your applications and to get access to all the features.
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