mongomodel 0.1.5 → 0.1.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.
@@ -0,0 +1 @@
1
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source "http://gemcutter.org"
2
+ git "git://github.com/rails/rails.git"
3
+
4
+ gem "activemodel"
5
+ gem "activesupport"
6
+
7
+ gem "mongo"
8
+ gem "bson"
9
+ gem "bson_ext"
10
+
11
+ gem "rspec"
data/Rakefile CHANGED
@@ -36,9 +36,10 @@ begin
36
36
  gem.authors = ["Sam Pohlenz"]
37
37
  gem.version = MongoModel::VERSION
38
38
 
39
- gem.add_dependency('activesupport', '>= 3.0.pre')
40
- gem.add_dependency('activemodel', '>= 3.0.pre')
41
- gem.add_dependency('mongo', '>= 0.18.3')
39
+ gem.add_dependency('activesupport', '>= 3.0.0.beta3')
40
+ gem.add_dependency('activemodel', '>= 3.0.0.beta3')
41
+ gem.add_dependency('mongo', '>= 0.20.1')
42
+ gem.add_dependency('bson', '>= 0.20.1')
42
43
  end
43
44
 
44
45
  Jeweler::GemcutterTasks.new
@@ -2,6 +2,16 @@
2
2
 
3
3
  puts "Loading MongoModel sandbox..."
4
4
 
5
+ begin
6
+ # Try to require the preresolved locked set of gems.
7
+ require File.expand_path('../../.bundle/environment', __FILE__)
8
+ rescue LoadError
9
+ # Fall back on doing an unlocked resolve at runtime.
10
+ require "rubygems"
11
+ require "bundler"
12
+ Bundler.setup
13
+ end
14
+
5
15
  $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
6
16
 
7
17
  require 'irb'
@@ -4,6 +4,10 @@ module MongoModel
4
4
 
5
5
  include ActiveModel::Conversion
6
6
 
7
+ def persisted?
8
+ !new_record?
9
+ end
10
+
7
11
  module ClassMethods
8
12
  include ActiveModel::Naming
9
13
  end
@@ -37,6 +37,10 @@ module MongoModel
37
37
  def polymorphic?
38
38
  options[:polymorphic]
39
39
  end
40
+
41
+ def scope_options
42
+ options.slice(:conditions, :select, :offset, :limit, :order)
43
+ end
40
44
 
41
45
  def self.properties(&block)
42
46
  block_given? ? write_inheritable_attribute(:properties, block) : read_inheritable_attribute(:properties)
@@ -47,7 +47,7 @@ module MongoModel
47
47
  end
48
48
 
49
49
  def load_target
50
- @target = @association.find_target unless loaded?
50
+ @target = association.find_target unless loaded?
51
51
  loaded!
52
52
  rescue MongoModel::DocumentNotFound
53
53
  reset
@@ -16,10 +16,12 @@ module MongoModel
16
16
 
17
17
  methods do |association|
18
18
  define_method(association.name) do |*args|
19
- force_reload = args.first || false
19
+ force_reload = args.first unless args.empty?
20
20
 
21
- associations[association.name].proxy.reset if force_reload
22
- associations[association.name].proxy
21
+ proxy = associations[association.name].proxy
22
+
23
+ proxy.reset if force_reload
24
+ proxy.target.nil? ? nil : proxy
23
25
  end
24
26
 
25
27
  define_method("#{association.name}=") { |obj| associations[association.name].replace(obj) }
@@ -51,16 +53,16 @@ module MongoModel
51
53
  end
52
54
 
53
55
  def replace(obj)
54
- ensure_class(obj) unless polymorphic?
56
+ ensure_class(obj) if obj && !polymorphic?
55
57
 
56
- instance[foreign_key] = obj.id
57
- instance[type_key] = obj.class if polymorphic?
58
+ instance[foreign_key] = obj ? obj.id : nil
59
+ instance[type_key] = obj ? obj.class : nil if polymorphic?
58
60
 
59
61
  super
60
62
  end
61
63
 
62
64
  def find_target
63
- target_class.find(target_id) unless target_id.nil? || target_class.nil?
65
+ target_class.find(target_id) if target_id && target_class
64
66
  end
65
67
  end
66
68
  end
@@ -23,7 +23,7 @@ module MongoModel
23
23
  delegate :foreign_key, :inverse_of, :to => :definition
24
24
 
25
25
  def find_target
26
- klass.find(:all, :conditions => { foreign_key => instance.id }) + new_documents
26
+ send_to_klass_with_scope(:all) + new_documents
27
27
  end
28
28
 
29
29
  def build(*args, &block)
@@ -44,6 +44,18 @@ module MongoModel
44
44
  end
45
45
  end
46
46
 
47
+ def create!(*args, &block)
48
+ klass.create!(*args) do |doc|
49
+ if doc.respond_to?("#{inverse_of}=")
50
+ doc.send("#{inverse_of}=", instance)
51
+ else
52
+ doc[foreign_key] = instance.id
53
+ end
54
+
55
+ block.call(doc) if block
56
+ end
57
+ end
58
+
47
59
  def replace(array)
48
60
  ensure_class(array)
49
61
  array.each { |doc| assign(doc) }
@@ -60,13 +72,25 @@ module MongoModel
60
72
  doc.save(false) unless doc.new_record?
61
73
  end
62
74
 
75
+ def unset(doc)
76
+ if doc.respond_to?("#{inverse_of}=")
77
+ doc.send("#{inverse_of}=", nil) if doc.send(inverse_of) == instance
78
+ else
79
+ doc[foreign_key] = nil if doc[foreign_key] == instance.id
80
+ end
81
+
82
+ doc.save(false) unless doc.new_record?
83
+ end
84
+
63
85
  def send_to_klass_with_scope(*args, &block)
64
- fk = foreign_key
65
- id = instance.id
86
+ scope_options = definition.scope_options
87
+ fk_conditions = { foreign_key => instance.id }
66
88
 
67
89
  klass.instance_eval do
68
- with_scope(:find => { :conditions => { fk => id } }) do
69
- send(*args, &block)
90
+ with_scope(:find => { :conditions => fk_conditions }) do
91
+ with_scope(:find => scope_options) do
92
+ send(*args, &block)
93
+ end
70
94
  end
71
95
  end
72
96
  end
@@ -99,27 +123,31 @@ module MongoModel
99
123
  doc
100
124
  end
101
125
 
102
- def []=(index, doc)
103
- ensure_class(doc)
104
- association.assign(doc)
105
- super if loaded?
106
- self
126
+ def create!(*args, &block)
127
+ doc = association.create!(*args, &block)
128
+ self << doc
129
+ doc
107
130
  end
108
131
 
109
- def <<(doc)
132
+ def []=(index, doc)
110
133
  ensure_class(doc)
134
+ association.unset(target[index]) if target[index]
111
135
  association.assign(doc)
112
136
  super if loaded?
113
137
  self
114
138
  end
115
139
 
116
- def concat(documents)
140
+ def <<(*documents)
141
+ documents.flatten!
117
142
  ensure_class(documents)
118
143
  documents.each { |doc| association.assign(doc) }
119
144
  super if loaded?
120
145
  self
121
146
  end
122
147
 
148
+ alias_method :push, :<<
149
+ alias_method :concat, :<<
150
+
123
151
  def insert(index, doc)
124
152
  ensure_class(doc)
125
153
  association.assign(doc)
@@ -127,17 +155,22 @@ module MongoModel
127
155
  self
128
156
  end
129
157
 
130
- def push(*documents)
158
+ def unshift(*documents)
131
159
  ensure_class(documents)
132
160
  documents.each { |doc| association.assign(doc) }
133
161
  super if loaded?
134
162
  self
135
163
  end
136
164
 
137
- def unshift(*documents)
138
- ensure_class(documents)
139
- documents.each { |doc| association.assign(doc) }
140
- super if loaded?
165
+ def delete(doc)
166
+ association.unset(doc)
167
+ super
168
+ self
169
+ end
170
+
171
+ def delete_at(index)
172
+ association.unset(target[index])
173
+ super
141
174
  self
142
175
  end
143
176
 
@@ -71,7 +71,7 @@ module MongoModel
71
71
  def class_for_type(type)
72
72
  klass = type.constantize
73
73
 
74
- if (subclasses + [name]).include?(type)
74
+ if klass.ancestors.include?(self)
75
75
  klass
76
76
  else
77
77
  raise DocumentNotFound, "Document not of the correct type (got #{type})"
@@ -79,7 +79,7 @@ module MongoModel
79
79
  args << keys.map { |k, o| [k, o == :ascending ? 1 : -1] }.sort_by { |k| k.first.to_s }
80
80
  end
81
81
 
82
- args << true if unique?
82
+ args << { :unique => true } if unique?
83
83
 
84
84
  args
85
85
  end
@@ -51,7 +51,7 @@ module MongoModel
51
51
  end
52
52
 
53
53
  def generate_id
54
- ::Mongo::ObjectID.new.to_s
54
+ ::BSON::ObjectID.new.to_s
55
55
  end
56
56
 
57
57
  module ClassMethods
@@ -1,6 +1,6 @@
1
1
  require 'active_support/core_ext/module/aliasing'
2
2
  require 'active_support/core_ext/module/delegation'
3
- require 'active_support/core_ext/object/metaclass'
3
+ require 'active_support/core_ext/kernel/singleton_class'
4
4
 
5
5
  module MongoModel
6
6
  module DocumentExtensions
@@ -23,7 +23,7 @@ module MongoModel
23
23
  def named_scope(name, options={})
24
24
  named_scopes[name] = options
25
25
 
26
- metaclass.instance_eval do
26
+ singleton_class.instance_eval do
27
27
  define_method(name) do |*args|
28
28
  scope(name).apply(*args)
29
29
  end
@@ -1,9 +1,5 @@
1
1
  module MongoModel
2
2
  class EmbeddedDocument
3
- def to_param
4
- id
5
- end
6
-
7
3
  def ==(other)
8
4
  other.is_a?(self.class) && other.attributes == attributes
9
5
  end
@@ -1,5 +1,3 @@
1
- require 'active_support/core_ext/object/blank'
2
-
3
1
  class Boolean < TrueClass; end
4
2
 
5
3
  class Symbol
@@ -10,63 +8,3 @@ class Symbol
10
8
  define_method(:asc) { MongoModel::MongoOrder::Clause.new(self, :ascending) }
11
9
  define_method(:desc) { MongoModel::MongoOrder::Clause.new(self, :descending) }
12
10
  end
13
-
14
- class Class
15
- # Rubinius
16
- if defined?(Class.__subclasses__)
17
- def descendents
18
- subclasses = []
19
- __subclasses__.each {|k| subclasses << k; subclasses.concat k.descendents }
20
- subclasses
21
- end
22
- else
23
- # MRI
24
- begin
25
- ObjectSpace.each_object(Class.new) {}
26
-
27
- def descendents
28
- subclasses = []
29
- ObjectSpace.each_object(class << self; self; end) do |k|
30
- subclasses << k unless k == self
31
- end
32
- subclasses
33
- end
34
- # JRuby
35
- rescue StandardError
36
- def descendents
37
- subclasses = []
38
- ObjectSpace.each_object(Class) do |k|
39
- subclasses << k if k < self
40
- end
41
- subclasses.uniq!
42
- subclasses
43
- end
44
- end
45
- end
46
-
47
- def reachable?
48
- eval("defined?(::#{self}) && ::#{self}.equal?(self)")
49
- end
50
-
51
- def subclasses
52
- Object.subclasses_of(self).map { |o| o.to_s }
53
- end
54
- end
55
-
56
- class Object
57
- def remove_subclasses_of(*superclasses) #:nodoc:
58
- Class.remove_class(*subclasses_of(*superclasses))
59
- end
60
-
61
- # Exclude this class unless it's a subclass of our supers and is defined.
62
- # We check defined? in case we find a removed class that has yet to be
63
- # garbage collected. This also fails for anonymous classes -- please
64
- # submit a patch if you have a workaround.
65
- def subclasses_of(*superclasses) #:nodoc:
66
- subclasses = []
67
- superclasses.each do |klass|
68
- subclasses.concat klass.descendents.select {|k| k.name.blank? || k.reachable?}
69
- end
70
- subclasses
71
- end
72
- end
@@ -1,3 +1,5 @@
1
+ require 'active_support/core_ext/class/subclasses'
2
+
1
3
  module MongoModel
2
4
  class MongoOptions
3
5
  ValidKeys = [ :conditions, :select, :offset, :limit, :order ]
@@ -1,3 +1,3 @@
1
1
  module MongoModel
2
- VERSION = "0.1.5"
2
+ VERSION = "0.1.6"
3
3
  end
@@ -0,0 +1,213 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{mongomodel}
8
+ s.version = "0.1.6"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Sam Pohlenz"]
12
+ s.date = %q{2010-04-16}
13
+ s.default_executable = %q{console}
14
+ s.description = %q{MongoModel is a MongoDB ORM for Ruby/Rails similar to ActiveRecord and DataMapper.}
15
+ s.email = %q{sam@sampohlenz.com}
16
+ s.executables = ["console"]
17
+ s.extra_rdoc_files = [
18
+ "LICENSE",
19
+ "README.md"
20
+ ]
21
+ s.files = [
22
+ ".gitignore",
23
+ "Gemfile",
24
+ "LICENSE",
25
+ "README.md",
26
+ "Rakefile",
27
+ "bin/console",
28
+ "lib/mongomodel.rb",
29
+ "lib/mongomodel/attributes/mongo.rb",
30
+ "lib/mongomodel/attributes/store.rb",
31
+ "lib/mongomodel/attributes/typecasting.rb",
32
+ "lib/mongomodel/concerns/abstract_class.rb",
33
+ "lib/mongomodel/concerns/activemodel.rb",
34
+ "lib/mongomodel/concerns/associations.rb",
35
+ "lib/mongomodel/concerns/associations/base/association.rb",
36
+ "lib/mongomodel/concerns/associations/base/definition.rb",
37
+ "lib/mongomodel/concerns/associations/base/proxy.rb",
38
+ "lib/mongomodel/concerns/associations/belongs_to.rb",
39
+ "lib/mongomodel/concerns/associations/has_many_by_foreign_key.rb",
40
+ "lib/mongomodel/concerns/associations/has_many_by_ids.rb",
41
+ "lib/mongomodel/concerns/attribute_methods.rb",
42
+ "lib/mongomodel/concerns/attribute_methods/before_type_cast.rb",
43
+ "lib/mongomodel/concerns/attribute_methods/dirty.rb",
44
+ "lib/mongomodel/concerns/attribute_methods/protected.rb",
45
+ "lib/mongomodel/concerns/attribute_methods/query.rb",
46
+ "lib/mongomodel/concerns/attribute_methods/read.rb",
47
+ "lib/mongomodel/concerns/attribute_methods/write.rb",
48
+ "lib/mongomodel/concerns/attributes.rb",
49
+ "lib/mongomodel/concerns/callbacks.rb",
50
+ "lib/mongomodel/concerns/logging.rb",
51
+ "lib/mongomodel/concerns/pretty_inspect.rb",
52
+ "lib/mongomodel/concerns/properties.rb",
53
+ "lib/mongomodel/concerns/record_status.rb",
54
+ "lib/mongomodel/concerns/serialization.rb",
55
+ "lib/mongomodel/concerns/timestamps.rb",
56
+ "lib/mongomodel/concerns/translation.rb",
57
+ "lib/mongomodel/concerns/validations.rb",
58
+ "lib/mongomodel/concerns/validations/associated.rb",
59
+ "lib/mongomodel/document.rb",
60
+ "lib/mongomodel/document/callbacks.rb",
61
+ "lib/mongomodel/document/dynamic_finders.rb",
62
+ "lib/mongomodel/document/finders.rb",
63
+ "lib/mongomodel/document/indexes.rb",
64
+ "lib/mongomodel/document/optimistic_locking.rb",
65
+ "lib/mongomodel/document/persistence.rb",
66
+ "lib/mongomodel/document/scopes.rb",
67
+ "lib/mongomodel/document/validations.rb",
68
+ "lib/mongomodel/document/validations/uniqueness.rb",
69
+ "lib/mongomodel/embedded_document.rb",
70
+ "lib/mongomodel/locale/en.yml",
71
+ "lib/mongomodel/support/collection.rb",
72
+ "lib/mongomodel/support/configuration.rb",
73
+ "lib/mongomodel/support/core_extensions.rb",
74
+ "lib/mongomodel/support/exceptions.rb",
75
+ "lib/mongomodel/support/mongo_options.rb",
76
+ "lib/mongomodel/support/types.rb",
77
+ "lib/mongomodel/support/types/array.rb",
78
+ "lib/mongomodel/support/types/boolean.rb",
79
+ "lib/mongomodel/support/types/custom.rb",
80
+ "lib/mongomodel/support/types/date.rb",
81
+ "lib/mongomodel/support/types/float.rb",
82
+ "lib/mongomodel/support/types/hash.rb",
83
+ "lib/mongomodel/support/types/integer.rb",
84
+ "lib/mongomodel/support/types/object.rb",
85
+ "lib/mongomodel/support/types/string.rb",
86
+ "lib/mongomodel/support/types/symbol.rb",
87
+ "lib/mongomodel/support/types/time.rb",
88
+ "lib/mongomodel/version.rb",
89
+ "mongomodel.gemspec",
90
+ "spec/mongomodel/attributes/store_spec.rb",
91
+ "spec/mongomodel/concerns/activemodel_spec.rb",
92
+ "spec/mongomodel/concerns/associations/belongs_to_spec.rb",
93
+ "spec/mongomodel/concerns/associations/has_many_by_foreign_key_spec.rb",
94
+ "spec/mongomodel/concerns/associations/has_many_by_ids_spec.rb",
95
+ "spec/mongomodel/concerns/attribute_methods/before_type_cast_spec.rb",
96
+ "spec/mongomodel/concerns/attribute_methods/dirty_spec.rb",
97
+ "spec/mongomodel/concerns/attribute_methods/protected_spec.rb",
98
+ "spec/mongomodel/concerns/attribute_methods/query_spec.rb",
99
+ "spec/mongomodel/concerns/attribute_methods/read_spec.rb",
100
+ "spec/mongomodel/concerns/attribute_methods/write_spec.rb",
101
+ "spec/mongomodel/concerns/attributes_spec.rb",
102
+ "spec/mongomodel/concerns/callbacks_spec.rb",
103
+ "spec/mongomodel/concerns/logging_spec.rb",
104
+ "spec/mongomodel/concerns/pretty_inspect_spec.rb",
105
+ "spec/mongomodel/concerns/properties_spec.rb",
106
+ "spec/mongomodel/concerns/serialization/json_serialization_spec.rb",
107
+ "spec/mongomodel/concerns/timestamps_spec.rb",
108
+ "spec/mongomodel/concerns/translation_spec.rb",
109
+ "spec/mongomodel/concerns/validations_spec.rb",
110
+ "spec/mongomodel/document/callbacks_spec.rb",
111
+ "spec/mongomodel/document/dynamic_finders_spec.rb",
112
+ "spec/mongomodel/document/finders_spec.rb",
113
+ "spec/mongomodel/document/indexes_spec.rb",
114
+ "spec/mongomodel/document/optimistic_locking_spec.rb",
115
+ "spec/mongomodel/document/persistence_spec.rb",
116
+ "spec/mongomodel/document/scopes_spec.rb",
117
+ "spec/mongomodel/document/validations/uniqueness_spec.rb",
118
+ "spec/mongomodel/document/validations_spec.rb",
119
+ "spec/mongomodel/document_spec.rb",
120
+ "spec/mongomodel/embedded_document_spec.rb",
121
+ "spec/mongomodel/mongomodel_spec.rb",
122
+ "spec/mongomodel/support/collection_spec.rb",
123
+ "spec/mongomodel/support/mongo_options_spec.rb",
124
+ "spec/mongomodel/support/property_spec.rb",
125
+ "spec/spec.opts",
126
+ "spec/spec_helper.rb",
127
+ "spec/specdoc.opts",
128
+ "spec/support/callbacks.rb",
129
+ "spec/support/helpers/define_class.rb",
130
+ "spec/support/helpers/specs_for.rb",
131
+ "spec/support/matchers/be_a_subclass_of.rb",
132
+ "spec/support/matchers/be_truthy.rb",
133
+ "spec/support/matchers/respond_to_boolean.rb",
134
+ "spec/support/matchers/run_callbacks.rb",
135
+ "spec/support/models.rb",
136
+ "spec/support/time.rb"
137
+ ]
138
+ s.homepage = %q{http://github.com/spohlenz/mongomodel}
139
+ s.rdoc_options = ["--charset=UTF-8"]
140
+ s.require_paths = ["lib"]
141
+ s.rubygems_version = %q{1.3.6}
142
+ s.summary = %q{MongoDB ORM for Ruby/Rails}
143
+ s.test_files = [
144
+ "spec/mongomodel/attributes/store_spec.rb",
145
+ "spec/mongomodel/concerns/activemodel_spec.rb",
146
+ "spec/mongomodel/concerns/associations/belongs_to_spec.rb",
147
+ "spec/mongomodel/concerns/associations/has_many_by_foreign_key_spec.rb",
148
+ "spec/mongomodel/concerns/associations/has_many_by_ids_spec.rb",
149
+ "spec/mongomodel/concerns/attribute_methods/before_type_cast_spec.rb",
150
+ "spec/mongomodel/concerns/attribute_methods/dirty_spec.rb",
151
+ "spec/mongomodel/concerns/attribute_methods/protected_spec.rb",
152
+ "spec/mongomodel/concerns/attribute_methods/query_spec.rb",
153
+ "spec/mongomodel/concerns/attribute_methods/read_spec.rb",
154
+ "spec/mongomodel/concerns/attribute_methods/write_spec.rb",
155
+ "spec/mongomodel/concerns/attributes_spec.rb",
156
+ "spec/mongomodel/concerns/callbacks_spec.rb",
157
+ "spec/mongomodel/concerns/logging_spec.rb",
158
+ "spec/mongomodel/concerns/pretty_inspect_spec.rb",
159
+ "spec/mongomodel/concerns/properties_spec.rb",
160
+ "spec/mongomodel/concerns/serialization/json_serialization_spec.rb",
161
+ "spec/mongomodel/concerns/timestamps_spec.rb",
162
+ "spec/mongomodel/concerns/translation_spec.rb",
163
+ "spec/mongomodel/concerns/validations_spec.rb",
164
+ "spec/mongomodel/document/callbacks_spec.rb",
165
+ "spec/mongomodel/document/dynamic_finders_spec.rb",
166
+ "spec/mongomodel/document/finders_spec.rb",
167
+ "spec/mongomodel/document/indexes_spec.rb",
168
+ "spec/mongomodel/document/optimistic_locking_spec.rb",
169
+ "spec/mongomodel/document/persistence_spec.rb",
170
+ "spec/mongomodel/document/scopes_spec.rb",
171
+ "spec/mongomodel/document/validations/uniqueness_spec.rb",
172
+ "spec/mongomodel/document/validations_spec.rb",
173
+ "spec/mongomodel/document_spec.rb",
174
+ "spec/mongomodel/embedded_document_spec.rb",
175
+ "spec/mongomodel/mongomodel_spec.rb",
176
+ "spec/mongomodel/support/collection_spec.rb",
177
+ "spec/mongomodel/support/mongo_options_spec.rb",
178
+ "spec/mongomodel/support/property_spec.rb",
179
+ "spec/spec_helper.rb",
180
+ "spec/support/callbacks.rb",
181
+ "spec/support/helpers/define_class.rb",
182
+ "spec/support/helpers/specs_for.rb",
183
+ "spec/support/matchers/be_a_subclass_of.rb",
184
+ "spec/support/matchers/be_truthy.rb",
185
+ "spec/support/matchers/respond_to_boolean.rb",
186
+ "spec/support/matchers/run_callbacks.rb",
187
+ "spec/support/models.rb",
188
+ "spec/support/time.rb"
189
+ ]
190
+
191
+ if s.respond_to? :specification_version then
192
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
193
+ s.specification_version = 3
194
+
195
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
196
+ s.add_runtime_dependency(%q<activesupport>, [">= 3.0.0.beta3"])
197
+ s.add_runtime_dependency(%q<activemodel>, [">= 3.0.0.beta3"])
198
+ s.add_runtime_dependency(%q<mongo>, [">= 0.20.1"])
199
+ s.add_runtime_dependency(%q<bson>, [">= 0.20.1"])
200
+ else
201
+ s.add_dependency(%q<activesupport>, [">= 3.0.0.beta3"])
202
+ s.add_dependency(%q<activemodel>, [">= 3.0.0.beta3"])
203
+ s.add_dependency(%q<mongo>, [">= 0.20.1"])
204
+ s.add_dependency(%q<bson>, [">= 0.20.1"])
205
+ end
206
+ else
207
+ s.add_dependency(%q<activesupport>, [">= 3.0.0.beta3"])
208
+ s.add_dependency(%q<activemodel>, [">= 3.0.0.beta3"])
209
+ s.add_dependency(%q<mongo>, [">= 0.20.1"])
210
+ s.add_dependency(%q<bson>, [">= 0.20.1"])
211
+ end
212
+ end
213
+
@@ -1,33 +1,97 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  # Specs ported from ActiveModel::Lint::Tests
4
+ #
5
+ # These tests do not attempt to determine the semantic correctness of the
6
+ # returned values. For instance, you could implement valid? to always
7
+ # return true, and the tests would pass. It is up to you to ensure that
8
+ # the values are semantically meaningful.
9
+ #
10
+ # Objects you pass in are expected to return a compliant object from a
11
+ # call to to_model. It is perfectly fine for to_model to return self.
4
12
  module MongoModel
5
13
  specs_for(Document, EmbeddedDocument) do
6
14
  define_class(:TestModel, described_class)
7
15
 
8
16
  subject { TestModel.new.to_model }
9
17
 
10
- # valid?
11
- # ------
18
+ # == Responds to <tt>to_key</tt>
12
19
  #
13
- # Returns a boolean that specifies whether the object is in a valid or invalid
14
- # state.
15
- it { should respond_to_boolean(:valid?) }
16
-
17
- # new_record?
18
- # -----------
20
+ # Returns an Enumerable of all (primary) key attributes
21
+ # or nil if model.persisted? is false
22
+ it { should respond_to(:to_key) }
23
+
24
+ specify "to_key should return nil if subject.persisted? is false" do
25
+ subject.stub!(:persisted?).and_return(false)
26
+ subject.to_key.should be_nil
27
+ end
28
+
29
+ # == Responds to <tt>to_param</tt>
30
+ #
31
+ # Returns a string representing the object's key suitable for use in URLs
32
+ # or nil if model.persisted? is false.
33
+ #
34
+ # Implementers can decide to either raise an exception or provide a default
35
+ # in case the record uses a composite primary key. There are no tests for this
36
+ # behavior in lint because it doesn't make sense to force any of the possible
37
+ # implementation strategies on the implementer. However, if the resource is
38
+ # not persisted?, then to_param should always return nil.
39
+ it { should respond_to(:to_param) }
40
+
41
+ specify "to_param should return nil if subject.persisted? is false" do
42
+ subject.stub!(:persisted?).and_return(false)
43
+ subject.to_param.should be_nil
44
+ end
45
+
46
+ # == Responds to <tt>persisted?</tt>
19
47
  #
20
48
  # Returns a boolean that specifies whether the object has been persisted yet.
21
49
  # This is used when calculating the URL for an object. If the object is
22
50
  # not persisted, a form for that object, for instance, will be POSTed to the
23
51
  # collection. If it is persisted, a form for the object will put PUTed to the
24
52
  # URL for the object.
25
- it { should respond_to_boolean(:new_record?) }
26
- it { should respond_to_boolean(:destroyed?) }
53
+ it { should respond_to_boolean(:persisted?) }
27
54
 
28
- # errors
29
- # ------
55
+ # == Naming
30
56
  #
57
+ # Model.model_name must returns a string with some convenience methods as
58
+ # :human and :partial_path. Check ActiveModel::Naming for more information.
59
+ #
60
+ specify "the model class should respond to model_name" do
61
+ subject.class.should respond_to(:model_name)
62
+ end
63
+
64
+ it "should return strings for model_name" do
65
+ model_name = subject.class.model_name
66
+ model_name.should be_a_kind_of(String)
67
+ model_name.human.should be_a_kind_of(String)
68
+ model_name.partial_path.should be_a_kind_of(String)
69
+ model_name.singular.should be_a_kind_of(String)
70
+ model_name.plural.should be_a_kind_of(String)
71
+ end
72
+
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
+ # == Errors Testing
94
+ #
31
95
  # Returns an object that has :[] and :full_messages defined on it. See below
32
96
  # for more details.
33
97
  describe "errors" do
@@ -51,11 +115,5 @@ module MongoModel
51
115
  end
52
116
  end
53
117
  end
54
-
55
- describe "#model_name" do
56
- it "should return an ActiveModel::Name object" do
57
- TestModel.model_name.should == ActiveModel::Name.new(mock('TestModel class', :name => 'TestModel'))
58
- end
59
- end
60
118
  end
61
119
  end
@@ -20,6 +20,10 @@ module MongoModel
20
20
  subject.user.should == user
21
21
  end
22
22
 
23
+ it "should not be truthy" do
24
+ subject.user.should_not be_truthy
25
+ end
26
+
23
27
  describe "setting a subclass type" do
24
28
  it "should set successfully" do
25
29
  subject.user = special_user
@@ -47,12 +51,16 @@ module MongoModel
47
51
  reloaded.user.should == user
48
52
  end
49
53
 
54
+ it "should be truthy" do
55
+ subject.user.should be_truthy
56
+ end
57
+
50
58
  it "should allow the user to be reloaded" do
51
- reloaded.user.inspect
52
- reloaded.user.loaded?.should be_true
59
+ user = reloaded.user.target
53
60
 
54
- reloaded.user(true)
55
- reloaded.user.loaded?.should be_false
61
+ user.should equal(reloaded.user.target)
62
+ user.should equal(reloaded.user.target)
63
+ user.should_not equal(reloaded.user(true).target)
56
64
  end
57
65
 
58
66
  describe "setting a subclass type" do
@@ -18,7 +18,7 @@ module MongoModel
18
18
  end
19
19
  define_class(:IllustratedChapter, :Chapter)
20
20
  define_class(:Book, Document) do
21
- has_many :chapters, :by => :foreign_key
21
+ has_many :chapters, :by => :foreign_key, :limit => 5
22
22
  end
23
23
  define_class(:NonChapter, Document)
24
24
 
@@ -56,6 +56,13 @@ module MongoModel
56
56
  chapter3.book.should == subject
57
57
  end
58
58
 
59
+ it "should replace chapters with []=" do
60
+ subject.chapters[1] = chapter3
61
+ subject.chapters.should include(chapter1, chapter3)
62
+ subject.chapters.should_not include(chapter2)
63
+ #chapter2.book.should be_nil
64
+ end
65
+
59
66
  it "should add chapters with concat" do
60
67
  subject.chapters.concat([chapter3])
61
68
  subject.chapters.should include(chapter1, chapter2, chapter3)
@@ -89,21 +96,21 @@ module MongoModel
89
96
  # it "should clear chapters" do
90
97
  # subject.chapters.clear
91
98
  # subject.chapters.should be_empty
92
- # subject.chapter_ids.should be_empty
93
- # end
94
- #
95
- # it "should remove chapters with delete" do
96
- # subject.chapters.delete(chapter1)
97
- # subject.chapters.should == [chapter2]
98
- # subject.chapter_ids.should == [chapter2.id]
99
+ # [chapter1, chapter2].each { |c| c.book.should be_nil }
99
100
  # end
100
- #
101
- # it "should remove chapters with delete_at" do
102
- # subject.chapters.delete_at(0)
103
- # subject.chapters.should == [chapter2]
104
- # subject.chapter_ids.should == [chapter2.id]
105
- # end
106
- #
101
+
102
+ it "should remove chapters with delete" do
103
+ subject.chapters.delete(chapter1)
104
+ subject.chapters.should == [chapter2]
105
+ chapter1.book.should be_nil
106
+ end
107
+
108
+ it "should remove chapters with delete_at" do
109
+ subject.chapters.delete_at(0)
110
+ subject.chapters.should == [chapter2]
111
+ #chapter1.book.should be_nil
112
+ end
113
+
107
114
  # it "should remove chapters with delete_if" do
108
115
  # subject.chapters.delete_if { |c| c.id == chapter1.id }
109
116
  # subject.chapters.should == [chapter2]
@@ -138,9 +145,16 @@ module MongoModel
138
145
  result = subject.chapters.find(:all, :order => :id.desc)
139
146
  result.should == [chapter2, chapter1]
140
147
  end
148
+
149
+ it "should find chapters with association options" do
150
+ # Create bogus chapters
151
+ 10.times { subject.chapters.create! }
152
+
153
+ subject.chapters.all.size.should == 5 # limit clause
154
+ end
141
155
  end
142
156
 
143
- context "with chapters set" do
157
+ context "new instance with chapters set" do
144
158
  subject { Book.new(:chapters => [chapter1, chapter2]) }
145
159
  it_should_behave_like "accessing and manipulating a has_many :by => :foreign_key association"
146
160
  end
@@ -45,7 +45,7 @@ module MongoModel
45
45
 
46
46
  it "should create indexes on the collection" do
47
47
  Article.collection.should_receive(:create_index).with(:_type)
48
- Article.collection.should_receive(:create_index).with(:title, true)
48
+ Article.collection.should_receive(:create_index).with(:title, :unique => true)
49
49
  Article.collection.should_receive(:create_index).with([[:age, Mongo::DESCENDING]])
50
50
  Article.ensure_indexes!
51
51
  end
@@ -93,7 +93,7 @@ module MongoModel
93
93
  end
94
94
 
95
95
  it "should convert index with unique option to arguments for Mongo::Collection#create_index" do
96
- Index.new(:title, :unique => true).to_args.should == [:title, true]
96
+ Index.new(:title, :unique => true).to_args.should == [:title, { :unique => true }]
97
97
  end
98
98
 
99
99
  it "should convert index with descending key to arguments for Mongo::Collection#create_index" do
@@ -58,6 +58,12 @@ module MongoModel
58
58
  subject.should be_valid
59
59
  end
60
60
 
61
+ it "should generate correct error message" do
62
+ Article.create!(:title => 'Test')
63
+ subject.valid?
64
+ subject.errors[:title].should include('has already been taken')
65
+ end
66
+
61
67
  describe "beating the race condition" do
62
68
  before(:each) { Article.create!(:title => 'Test') }
63
69
  it_should_behave_like "beating the race condition"
@@ -1,4 +1,13 @@
1
- require 'rubygems'
1
+ begin
2
+ # Try to require the preresolved locked set of gems.
3
+ require File.expand_path('../../.bundle/environment', __FILE__)
4
+ rescue LoadError
5
+ # Fall back on doing an unlocked resolve at runtime.
6
+ require "rubygems"
7
+ require "bundler"
8
+ Bundler.setup
9
+ end
10
+
2
11
  require 'spec'
3
12
 
4
13
  # Require MongoModel library
@@ -0,0 +1,5 @@
1
+ Spec::Matchers.define(:be_truthy) do
2
+ match do |object|
3
+ !!object
4
+ end
5
+ end
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongomodel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 6
9
+ version: 0.1.6
5
10
  platform: ruby
6
11
  authors:
7
12
  - Sam Pohlenz
@@ -9,39 +14,67 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2010-02-19 00:00:00 +10:30
17
+ date: 2010-04-16 00:00:00 +09:30
13
18
  default_executable: console
14
19
  dependencies:
15
20
  - !ruby/object:Gem::Dependency
16
21
  name: activesupport
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
20
24
  requirements:
21
25
  - - ">="
22
26
  - !ruby/object:Gem::Version
23
- version: 3.0.pre
24
- version:
27
+ segments:
28
+ - 3
29
+ - 0
30
+ - 0
31
+ - beta3
32
+ version: 3.0.0.beta3
33
+ type: :runtime
34
+ version_requirements: *id001
25
35
  - !ruby/object:Gem::Dependency
26
36
  name: activemodel
27
- type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
30
39
  requirements:
31
40
  - - ">="
32
41
  - !ruby/object:Gem::Version
33
- version: 3.0.pre
34
- version:
42
+ segments:
43
+ - 3
44
+ - 0
45
+ - 0
46
+ - beta3
47
+ version: 3.0.0.beta3
48
+ type: :runtime
49
+ version_requirements: *id002
35
50
  - !ruby/object:Gem::Dependency
36
51
  name: mongo
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ segments:
58
+ - 0
59
+ - 20
60
+ - 1
61
+ version: 0.20.1
37
62
  type: :runtime
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
63
+ version_requirements: *id003
64
+ - !ruby/object:Gem::Dependency
65
+ name: bson
66
+ prerelease: false
67
+ requirement: &id004 !ruby/object:Gem::Requirement
40
68
  requirements:
41
69
  - - ">="
42
70
  - !ruby/object:Gem::Version
43
- version: 0.18.3
44
- version:
71
+ segments:
72
+ - 0
73
+ - 20
74
+ - 1
75
+ version: 0.20.1
76
+ type: :runtime
77
+ version_requirements: *id004
45
78
  description: MongoModel is a MongoDB ORM for Ruby/Rails similar to ActiveRecord and DataMapper.
46
79
  email: sam@sampohlenz.com
47
80
  executables:
@@ -52,6 +85,8 @@ extra_rdoc_files:
52
85
  - LICENSE
53
86
  - README.md
54
87
  files:
88
+ - .gitignore
89
+ - Gemfile
55
90
  - LICENSE
56
91
  - README.md
57
92
  - Rakefile
@@ -117,6 +152,7 @@ files:
117
152
  - lib/mongomodel/support/types/symbol.rb
118
153
  - lib/mongomodel/support/types/time.rb
119
154
  - lib/mongomodel/version.rb
155
+ - mongomodel.gemspec
120
156
  - spec/mongomodel/attributes/store_spec.rb
121
157
  - spec/mongomodel/concerns/activemodel_spec.rb
122
158
  - spec/mongomodel/concerns/associations/belongs_to_spec.rb
@@ -159,6 +195,7 @@ files:
159
195
  - spec/support/helpers/define_class.rb
160
196
  - spec/support/helpers/specs_for.rb
161
197
  - spec/support/matchers/be_a_subclass_of.rb
198
+ - spec/support/matchers/be_truthy.rb
162
199
  - spec/support/matchers/respond_to_boolean.rb
163
200
  - spec/support/matchers/run_callbacks.rb
164
201
  - spec/support/models.rb
@@ -176,18 +213,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
176
213
  requirements:
177
214
  - - ">="
178
215
  - !ruby/object:Gem::Version
216
+ segments:
217
+ - 0
179
218
  version: "0"
180
- version:
181
219
  required_rubygems_version: !ruby/object:Gem::Requirement
182
220
  requirements:
183
221
  - - ">="
184
222
  - !ruby/object:Gem::Version
223
+ segments:
224
+ - 0
185
225
  version: "0"
186
- version:
187
226
  requirements: []
188
227
 
189
228
  rubyforge_project:
190
- rubygems_version: 1.3.5
229
+ rubygems_version: 1.3.6
191
230
  signing_key:
192
231
  specification_version: 3
193
232
  summary: MongoDB ORM for Ruby/Rails
@@ -232,6 +271,7 @@ test_files:
232
271
  - spec/support/helpers/define_class.rb
233
272
  - spec/support/helpers/specs_for.rb
234
273
  - spec/support/matchers/be_a_subclass_of.rb
274
+ - spec/support/matchers/be_truthy.rb
235
275
  - spec/support/matchers/respond_to_boolean.rb
236
276
  - spec/support/matchers/run_callbacks.rb
237
277
  - spec/support/models.rb