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.
- data/.gitignore +1 -0
- data/Gemfile +11 -0
- data/Rakefile +4 -3
- data/bin/console +10 -0
- data/lib/mongomodel/concerns/activemodel.rb +4 -0
- data/lib/mongomodel/concerns/associations/base/definition.rb +4 -0
- data/lib/mongomodel/concerns/associations/base/proxy.rb +1 -1
- data/lib/mongomodel/concerns/associations/belongs_to.rb +9 -7
- data/lib/mongomodel/concerns/associations/has_many_by_foreign_key.rb +50 -17
- data/lib/mongomodel/concerns/attributes.rb +1 -1
- data/lib/mongomodel/document/indexes.rb +1 -1
- data/lib/mongomodel/document/persistence.rb +1 -1
- data/lib/mongomodel/document/scopes.rb +2 -2
- data/lib/mongomodel/embedded_document.rb +0 -4
- data/lib/mongomodel/support/core_extensions.rb +0 -62
- data/lib/mongomodel/support/mongo_options.rb +2 -0
- data/lib/mongomodel/version.rb +1 -1
- data/mongomodel.gemspec +213 -0
- data/spec/mongomodel/concerns/activemodel_spec.rb +76 -18
- data/spec/mongomodel/concerns/associations/belongs_to_spec.rb +12 -4
- data/spec/mongomodel/concerns/associations/has_many_by_foreign_key_spec.rb +30 -16
- data/spec/mongomodel/document/indexes_spec.rb +2 -2
- data/spec/mongomodel/document/validations/uniqueness_spec.rb +6 -0
- data/spec/spec_helper.rb +10 -1
- data/spec/support/matchers/be_truthy.rb +5 -0
- metadata +59 -19
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
.bundle
|
data/Gemfile
ADDED
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.
|
40
|
-
gem.add_dependency('activemodel', '>= 3.0.
|
41
|
-
gem.add_dependency('mongo', '>= 0.
|
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
|
data/bin/console
CHANGED
@@ -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'
|
@@ -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)
|
@@ -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
|
19
|
+
force_reload = args.first unless args.empty?
|
20
20
|
|
21
|
-
associations[association.name].proxy
|
22
|
-
|
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)
|
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)
|
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
|
-
|
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
|
-
|
65
|
-
|
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 =>
|
69
|
-
|
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
|
103
|
-
|
104
|
-
|
105
|
-
|
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
|
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
|
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
|
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
|
138
|
-
|
139
|
-
|
140
|
-
|
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
|
|
@@ -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/
|
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
|
-
|
26
|
+
singleton_class.instance_eval do
|
27
27
|
define_method(name) do |*args|
|
28
28
|
scope(name).apply(*args)
|
29
29
|
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
|
data/lib/mongomodel/version.rb
CHANGED
data/mongomodel.gemspec
ADDED
@@ -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
|
-
#
|
11
|
-
# ------
|
18
|
+
# == Responds to <tt>to_key</tt>
|
12
19
|
#
|
13
|
-
# Returns
|
14
|
-
#
|
15
|
-
it { should
|
16
|
-
|
17
|
-
|
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(:
|
26
|
-
it { should respond_to_boolean(:destroyed?) }
|
53
|
+
it { should respond_to_boolean(:persisted?) }
|
27
54
|
|
28
|
-
#
|
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.
|
52
|
-
reloaded.user.loaded?.should be_true
|
59
|
+
user = reloaded.user.target
|
53
60
|
|
54
|
-
reloaded.user
|
55
|
-
reloaded.user.
|
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
|
-
#
|
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
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
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"
|
data/spec/spec_helper.rb
CHANGED
@@ -1,4 +1,13 @@
|
|
1
|
-
|
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
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongomodel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
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-
|
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
|
-
|
18
|
-
|
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
|
-
|
24
|
-
|
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
|
-
|
28
|
-
|
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
|
-
|
34
|
-
|
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
|
-
|
39
|
-
|
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
|
-
|
44
|
-
|
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.
|
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
|