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