mongodb_model 2.0.2 → 2.1.0
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/Rakefile +1 -1
- data/lib/mongo/model/assignment.rb +2 -1
- data/lib/mongo/model/conversion.rb +15 -23
- data/lib/mongo/model/db.rb +13 -1
- data/lib/mongo/model/identity_map.rb +38 -0
- data/lib/mongo/model/integration/rad/tasks.rb +10 -0
- data/lib/mongo/model/integration/rad.rb +41 -0
- data/lib/mongo/model/integration/rails.rb +2 -0
- data/lib/mongo/model/load.rb +10 -8
- data/lib/mongo/model/misc.rb +9 -2
- data/lib/mongo/model/model.rb +12 -0
- data/lib/mongo/model/scope.rb +13 -1
- data/lib/mongo/model/spec.rb +6 -0
- data/lib/mongo/model/support/rson.rb +68 -0
- data/lib/mongo/model/validation.rb +31 -0
- data/lib/mongo/model.rb +2 -0
- data/lib/mongodb_model/gems.rb +0 -3
- data/spec/assignment_spec.rb +4 -1
- data/spec/attribute_convertors_spec.rb +2 -1
- data/spec/callbacks_spec.rb +1 -1
- data/spec/conversion_spec.rb +22 -14
- data/spec/crud_spec.rb +20 -4
- data/spec/misc_spec.rb +47 -6
- data/spec/query_spec.rb +3 -1
- data/spec/validation_spec.rb +22 -0
- metadata +13 -10
- data/lib/mongo/model/support.rb +0 -10
data/Rakefile
CHANGED
@@ -23,7 +23,8 @@ module Mongo::Model::Assignment
|
|
23
23
|
v = type.cast(v) if type
|
24
24
|
send "#{n}=", v
|
25
25
|
else
|
26
|
-
|
26
|
+
# Do nothing, just silently skip it.
|
27
|
+
# raise "mass assignment for :#{n} attribute not allowed!"
|
27
28
|
end
|
28
29
|
end
|
29
30
|
else
|
@@ -1,10 +1,12 @@
|
|
1
|
+
require 'mongo/model/support/rson'
|
2
|
+
|
1
3
|
module Mongo::Model::Conversion
|
2
4
|
def model_to_json *args, &block
|
3
|
-
|
5
|
+
to_rson(*args, &block).to_json
|
4
6
|
end
|
5
7
|
|
6
8
|
def model_to_xml *args, &block
|
7
|
-
|
9
|
+
to_rson(*args, &block).to_xml
|
8
10
|
end
|
9
11
|
|
10
12
|
alias_method :to_json, :model_to_json
|
@@ -19,13 +21,15 @@ module Mongo::Model::Conversion
|
|
19
21
|
alias_method :as_xml, :model_to_xml
|
20
22
|
end
|
21
23
|
|
22
|
-
def
|
24
|
+
def to_rson options = {}
|
25
|
+
options = {profile: options} if options.is_a? Symbol
|
26
|
+
|
23
27
|
if profile = options[:profile]
|
24
28
|
raise "no other optins are allowed when using :profile option!" if options.size > 1
|
25
29
|
profile_options = self.class.profiles[profile] || raise("profile :#{profile} not defined for #{self.class}!")
|
26
|
-
|
30
|
+
to_rson profile_options.merge(_profile: profile)
|
27
31
|
else
|
28
|
-
options.validate_options! :only, :except, :methods, :errors, :_profile
|
32
|
+
options.validate_options! :only, :except, :methods, :errors, :id, :_profile
|
29
33
|
child_options = options[:_profile] ? {profile: options[:_profile]} : {}
|
30
34
|
|
31
35
|
instance_variables = self.persistent_instance_variable_names
|
@@ -39,15 +43,15 @@ module Mongo::Model::Conversion
|
|
39
43
|
result = {}
|
40
44
|
instance_variables.each do |iv_name|
|
41
45
|
value = instance_variable_get iv_name
|
42
|
-
value =
|
43
|
-
result[iv_name[1.. -1].to_sym] = value
|
46
|
+
# value = convert_object value, :to_rson, child_options
|
47
|
+
result[iv_name[1.. -1].to_sym] = value.to_rson child_options
|
44
48
|
end
|
45
49
|
|
46
50
|
methods = options[:methods] ? Array(options[:methods]) : []
|
47
51
|
methods.each do |method|
|
48
52
|
value = send method
|
49
|
-
value =
|
50
|
-
result[method.to_sym] = value
|
53
|
+
# value = convert_object value, :to_rson, child_options
|
54
|
+
result[method.to_sym] = value.to_rson child_options
|
51
55
|
end
|
52
56
|
|
53
57
|
with_errors = options.include?(:errors) ? options[:errors] : true
|
@@ -57,24 +61,12 @@ module Mongo::Model::Conversion
|
|
57
61
|
result[:errors] = errors
|
58
62
|
end
|
59
63
|
|
64
|
+
result[:id] = _id if _id and (options[:id] != false)
|
65
|
+
|
60
66
|
result
|
61
67
|
end
|
62
68
|
end
|
63
69
|
|
64
|
-
protected
|
65
|
-
def convert_model obj, method, options
|
66
|
-
if obj.respond_to? :collect_with_value
|
67
|
-
# Array or Hash.
|
68
|
-
obj.collect_with_value{|v| convert_model v, method, options}
|
69
|
-
elsif obj.respond_to? method
|
70
|
-
# Model.
|
71
|
-
obj.send method, options
|
72
|
-
else
|
73
|
-
# Simple object.
|
74
|
-
obj
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
70
|
module ClassMethods
|
79
71
|
inheritable_accessor :profiles, {}
|
80
72
|
def profile name, options = {}
|
data/lib/mongo/model/db.rb
CHANGED
@@ -22,7 +22,19 @@ module Mongo::Model::Db
|
|
22
22
|
def default_collection_name
|
23
23
|
first_ancestor_class = ancestors.find{|a| a.is_a? Class} ||
|
24
24
|
raise("can't evaluate default collection name for #{self}!")
|
25
|
-
first_ancestor_class.alias
|
25
|
+
als = first_ancestor_class.alias
|
26
|
+
|
27
|
+
unless als.respond_to? :pluralize
|
28
|
+
warn <<-TEXT
|
29
|
+
WARN: It seems that there's no `String.pluralize` method, Mongo::Model needs it to automatically infer
|
30
|
+
collection name from the model class name.
|
31
|
+
Please specify collection name explicitly (like `collection :users`) or provide the `pluralize`
|
32
|
+
method.
|
33
|
+
TEXT
|
34
|
+
raise "collection name for #{first_ancestor_class} not defined (add it, like `collection :users`)!"
|
35
|
+
end
|
36
|
+
|
37
|
+
als.pluralize.underscore.to_sym
|
26
38
|
end
|
27
39
|
end
|
28
40
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Mongo::Model::IdentityMap
|
2
|
+
inherited do
|
3
|
+
Mongo::Model::IdentityMap.models.add self
|
4
|
+
end
|
5
|
+
|
6
|
+
def original
|
7
|
+
unless _cache[:original_cached]
|
8
|
+
_cache[:original_cached] = true
|
9
|
+
_cache[:original] = _id && self.class.get_from_identity_map(_id)
|
10
|
+
end
|
11
|
+
_cache[:original]
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
def identity_map
|
16
|
+
@identity_map ||= {}
|
17
|
+
end
|
18
|
+
|
19
|
+
def get_from_identity_map id
|
20
|
+
doc = identity_map[id]
|
21
|
+
from_mongo doc if doc
|
22
|
+
end
|
23
|
+
|
24
|
+
def from_mongo doc
|
25
|
+
model = super doc
|
26
|
+
model.class.identity_map[model._id] = doc if model._id
|
27
|
+
model
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class << self
|
32
|
+
def models
|
33
|
+
@models ||= Set.new
|
34
|
+
end
|
35
|
+
|
36
|
+
def clear; models.collect(&:identity_map).every.clear end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'mongo/migration/tasks'
|
2
|
+
|
3
|
+
namespace :db do
|
4
|
+
desc "Internal task to prepare migration environment"
|
5
|
+
task migration_evnironment: :environment do
|
6
|
+
require 'mongo/migration'
|
7
|
+
|
8
|
+
Dir["#{rad.runtime_path}/db/**/*.rb"].each{|f| require f.sub(/\.rb$/, '')}
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# Registering it as component.
|
2
|
+
|
3
|
+
class Mongo::Model::Component
|
4
|
+
attr_accessor :db
|
5
|
+
attr_required :db
|
6
|
+
|
7
|
+
attr_accessor :fs
|
8
|
+
attr_required :fs
|
9
|
+
end
|
10
|
+
|
11
|
+
rad.register :models do
|
12
|
+
Mongo::Model::Component.new
|
13
|
+
end
|
14
|
+
|
15
|
+
# Using DB connection setting defined in component's config file.
|
16
|
+
Mongo.metaclass_eval do
|
17
|
+
def db name
|
18
|
+
config = rad.models.db[name.to_s] || raise("no database config for #{name} alias!")
|
19
|
+
host, port, options = config['host'], config['port'], (config['options'] || {})
|
20
|
+
connection = self.connection host, port, options
|
21
|
+
db_name = config['name'] || raise("no database name for #{name} alias!")
|
22
|
+
connection.db db_name
|
23
|
+
end
|
24
|
+
cache_method_with_params :db
|
25
|
+
|
26
|
+
def connection host, port, options
|
27
|
+
options[:logger] = rad.logger unless options.include? :logger
|
28
|
+
Mongo::Connection.new host, port, options
|
29
|
+
end
|
30
|
+
cache_method_with_params :connection
|
31
|
+
end
|
32
|
+
|
33
|
+
# Localization
|
34
|
+
|
35
|
+
Mongo::Model::Misc.class_eval do
|
36
|
+
def t *args; rad.locale.t *args end
|
37
|
+
end
|
38
|
+
|
39
|
+
Mongo::Model::Misc::ClassMethods.class_eval do
|
40
|
+
def t *args; rad.locale.t *args end
|
41
|
+
end
|
data/lib/mongo/model/load.rb
CHANGED
@@ -1,17 +1,14 @@
|
|
1
|
-
require 'mongo/object'
|
2
1
|
require 'ruby_ext'
|
3
2
|
|
4
3
|
module Mongo::Model; end
|
5
4
|
|
6
5
|
%w(
|
7
|
-
support
|
8
|
-
|
9
6
|
db
|
10
7
|
conversion
|
11
8
|
assignment
|
12
9
|
callbacks
|
13
|
-
validation
|
14
10
|
crud
|
11
|
+
validation
|
15
12
|
query
|
16
13
|
query_mixin
|
17
14
|
scope
|
@@ -20,17 +17,18 @@ module Mongo::Model; end
|
|
20
17
|
model
|
21
18
|
).each{|f| require "mongo/model/#{f}"}
|
22
19
|
|
20
|
+
# Assembling model.
|
23
21
|
module Mongo
|
24
22
|
module Model
|
25
|
-
autoload :
|
23
|
+
autoload :IdentityMap, 'mongo/model/identity_map'
|
26
24
|
|
27
25
|
inherit \
|
28
26
|
Db,
|
29
27
|
Conversion,
|
30
28
|
Assignment,
|
31
29
|
Callbacks,
|
32
|
-
Validation,
|
33
30
|
Crud,
|
31
|
+
Validation,
|
34
32
|
QueryMixin,
|
35
33
|
Scope,
|
36
34
|
AttributeConvertors,
|
@@ -45,15 +43,19 @@ Mongo.defaults.merge! \
|
|
45
43
|
safe: true,
|
46
44
|
generate_id: true
|
47
45
|
|
48
|
-
#
|
46
|
+
# Integrations.
|
47
|
+
|
49
48
|
unless $dont_use_rails
|
50
49
|
require 'mongo/model/integration/rails' if defined? Rails
|
51
50
|
end
|
52
51
|
|
53
|
-
# Integration with Validatable2
|
54
52
|
unless $dont_use_validatable
|
55
53
|
require 'validatable'
|
56
54
|
require 'mongo/model/integration/validatable'
|
57
55
|
require 'mongo/model/integration/validatable/uniqueness_validator'
|
58
56
|
Mongo::Model.inherit Validatable::Model
|
57
|
+
end
|
58
|
+
|
59
|
+
unless $dont_use_file_model
|
60
|
+
Mongo::Model.autoload :FileModel, 'mongo/model/integration/file_model'
|
59
61
|
end
|
data/lib/mongo/model/misc.rb
CHANGED
@@ -8,7 +8,6 @@ module Mongo::Model::Misc
|
|
8
8
|
self.updated_at = now
|
9
9
|
end
|
10
10
|
|
11
|
-
|
12
11
|
def _cache
|
13
12
|
@_cache ||= {}
|
14
13
|
end
|
@@ -32,7 +31,11 @@ module Mongo::Model::Misc
|
|
32
31
|
end
|
33
32
|
|
34
33
|
def original
|
35
|
-
|
34
|
+
unless _cache[:original_cached]
|
35
|
+
_cache[:original_cached] = true
|
36
|
+
_cache[:original] = _id && self.class.by_id(_id)
|
37
|
+
end
|
38
|
+
_cache[:original]
|
36
39
|
end
|
37
40
|
|
38
41
|
module ClassMethods
|
@@ -41,5 +44,9 @@ module Mongo::Model::Misc
|
|
41
44
|
before_create :update_created_at
|
42
45
|
before_save :update_updated_at
|
43
46
|
end
|
47
|
+
|
48
|
+
def create_index *args
|
49
|
+
collection.create_index *args
|
50
|
+
end
|
44
51
|
end
|
45
52
|
end
|
data/lib/mongo/model/model.rb
CHANGED
@@ -70,5 +70,17 @@ module Mongo::Model
|
|
70
70
|
list.collect!{|n| :"@#{n}"}
|
71
71
|
if list.empty? then _embedded else _embedded.push(*list) end
|
72
72
|
end
|
73
|
+
|
74
|
+
def from_mongo doc
|
75
|
+
model = ::Mongo::Object.from_mongo doc
|
76
|
+
model.run_after_callbacks :build, :build
|
77
|
+
model
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class << self
|
82
|
+
def originals
|
83
|
+
@originals ||= {}
|
84
|
+
end
|
73
85
|
end
|
74
86
|
end
|
data/lib/mongo/model/scope.rb
CHANGED
@@ -87,9 +87,21 @@ module Mongo::Model::Scope
|
|
87
87
|
list = list.collect{|item| item.is_a?(Array) ? item : [item, 1]}
|
88
88
|
query({}, sort: list)
|
89
89
|
end
|
90
|
+
alias_method :sort_by, :sort
|
90
91
|
def snapshot; query({}, snapshot: true) end
|
91
92
|
|
92
|
-
|
93
|
+
PER_PAGE, MAX_PER_PAGE = 25, 100
|
94
|
+
def paginate *args
|
95
|
+
args.size.must.be_in 1..2
|
96
|
+
if args.size == 2
|
97
|
+
page, per_page = *args
|
98
|
+
else
|
99
|
+
options = args.first
|
100
|
+
page, per_page = options[:page], options[:per_page]
|
101
|
+
end
|
102
|
+
page ||= 1
|
103
|
+
per_page ||= PER_PAGE
|
104
|
+
per_page = MAX_PER_PAGE if per_page > MAX_PER_PAGE
|
93
105
|
skip((page - 1) * per_page).limit(per_page)
|
94
106
|
end
|
95
107
|
|
data/lib/mongo/model/spec.rb
CHANGED
@@ -0,0 +1,68 @@
|
|
1
|
+
class Object
|
2
|
+
def rson?
|
3
|
+
false
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
[
|
8
|
+
Time,
|
9
|
+
FalseClass,
|
10
|
+
TrueClass,
|
11
|
+
Numeric,
|
12
|
+
Symbol,
|
13
|
+
String,
|
14
|
+
NilClass,
|
15
|
+
].each do |klass|
|
16
|
+
klass.class_eval do
|
17
|
+
def to_rson options = {}
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
def rson?
|
22
|
+
true
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# [
|
28
|
+
# String
|
29
|
+
# ].each do |klass|
|
30
|
+
# klass.class_eval do
|
31
|
+
# def to_rson options = {}
|
32
|
+
# self.to_sym
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# def rson?
|
36
|
+
# false
|
37
|
+
# end
|
38
|
+
# end
|
39
|
+
# end
|
40
|
+
|
41
|
+
Array.class_eval do
|
42
|
+
def to_rson options = {}
|
43
|
+
collect{|v| v.to_rson(options)}
|
44
|
+
end
|
45
|
+
|
46
|
+
def rson?
|
47
|
+
all?{|v| v.rson?}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
[Hash, OpenObject].each do |klass|
|
52
|
+
klass.class_eval do
|
53
|
+
def to_rson options = {}
|
54
|
+
r = self.class.new
|
55
|
+
each do |k, v|
|
56
|
+
r[k.to_sym] = v.to_rson(options)
|
57
|
+
end
|
58
|
+
r
|
59
|
+
end
|
60
|
+
|
61
|
+
def rson?
|
62
|
+
each do |k, v|
|
63
|
+
return false unless k.rson? and v.rson?
|
64
|
+
end
|
65
|
+
true
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -5,7 +5,38 @@ module Mongo::Model::Validation
|
|
5
5
|
end
|
6
6
|
def invalid?(options = {}); !valid?(options) end
|
7
7
|
|
8
|
+
# Catching erros during CRUD and adding it to errors, like unique index.
|
9
|
+
|
10
|
+
def create_object *args
|
11
|
+
with_exceptions_as_errors do
|
12
|
+
super
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def update_object *args
|
17
|
+
with_exceptions_as_errors do
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def delete_object *args
|
23
|
+
with_exceptions_as_errors do
|
24
|
+
super
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
8
28
|
protected
|
29
|
+
def with_exceptions_as_errors &block
|
30
|
+
block.call
|
31
|
+
rescue Mongo::OperationFailure => e
|
32
|
+
if [11000, 11001].include? e.error_code
|
33
|
+
errors.add :base, "not unique value!"
|
34
|
+
false
|
35
|
+
else
|
36
|
+
raise e
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
9
40
|
def run_validations options = {}
|
10
41
|
with_model_callbacks [:validate], options, [self] do
|
11
42
|
# Validating main model.
|
data/lib/mongo/model.rb
CHANGED
data/lib/mongodb_model/gems.rb
CHANGED
data/spec/assignment_spec.rb
CHANGED
@@ -38,9 +38,12 @@ describe 'Attribute assignment' do
|
|
38
38
|
|
39
39
|
u = User.new
|
40
40
|
u.set name: 'Alex', has_mail: '1', age: '31', position: [11, 34]
|
41
|
-
-> {u.set name: 'Alex', banned: false}.should raise_error(/not allowed/)
|
42
41
|
[u.name, u.has_mail, u.age, u.position, u.banned].should == ['Alex', true, 31, [11, 34], nil]
|
43
42
|
|
43
|
+
# Should skip not allowed attributes.
|
44
|
+
u.set banned: false
|
45
|
+
u.banned.should be_nil
|
46
|
+
|
44
47
|
# should allow to forcefully cast and update any attribute
|
45
48
|
u.set! banned: '0'
|
46
49
|
u.banned.should == false
|
data/spec/callbacks_spec.rb
CHANGED
data/spec/conversion_spec.rb
CHANGED
@@ -40,7 +40,7 @@ describe 'Conversion' do
|
|
40
40
|
|
41
41
|
it "should work without arguments" do
|
42
42
|
post = build_post_with_comment
|
43
|
-
post.
|
43
|
+
post.to_rson.should == {
|
44
44
|
text: 'StarCraft releasing soon!',
|
45
45
|
token: 'secret',
|
46
46
|
comments: [
|
@@ -51,14 +51,14 @@ describe 'Conversion' do
|
|
51
51
|
|
52
52
|
it "should accept :only, :except and :methods options" do
|
53
53
|
post = build_post_with_comment
|
54
|
-
post.
|
55
|
-
post.
|
54
|
+
post.to_rson(only: :text).should == {text: 'StarCraft releasing soon!'}
|
55
|
+
post.to_rson(except: :token).should == {
|
56
56
|
text: 'StarCraft releasing soon!',
|
57
57
|
comments: [
|
58
58
|
{text: 'Cool!'}
|
59
59
|
]
|
60
60
|
}
|
61
|
-
post.
|
61
|
+
post.to_rson(only: [], methods: :teaser).should == {teaser: 'StarCraft r'}
|
62
62
|
end
|
63
63
|
|
64
64
|
it "should use conversion profiles" do
|
@@ -68,13 +68,21 @@ describe 'Conversion' do
|
|
68
68
|
|
69
69
|
post = build_post_with_comment
|
70
70
|
|
71
|
-
-> {post.
|
71
|
+
-> {post.to_rson(profile: :public)}.should raise_error(/profile :public not defined for Comment/)
|
72
72
|
|
73
73
|
Comment.class_eval do
|
74
74
|
profile :public
|
75
75
|
end
|
76
76
|
|
77
|
-
post.
|
77
|
+
post.to_rson(profile: :public).should == {
|
78
|
+
text: 'StarCraft releasing soon!',
|
79
|
+
teaser: 'StarCraft r',
|
80
|
+
comments: [
|
81
|
+
{text: 'Cool!'}
|
82
|
+
]
|
83
|
+
}
|
84
|
+
|
85
|
+
post.to_rson(:public).should == {
|
78
86
|
text: 'StarCraft releasing soon!',
|
79
87
|
teaser: 'StarCraft r',
|
80
88
|
comments: [
|
@@ -91,29 +99,29 @@ describe 'Conversion' do
|
|
91
99
|
post = Post.new text: 'StarCraft releasing soon!'
|
92
100
|
post.valid?.should be_false
|
93
101
|
|
94
|
-
post.
|
102
|
+
post.to_rson.should == {
|
95
103
|
text: 'StarCraft releasing soon!',
|
96
104
|
errors: {token: ["can't be empty"]}
|
97
105
|
}
|
98
106
|
|
99
|
-
post.
|
107
|
+
post.to_rson(errors: false).should == {
|
100
108
|
text: 'StarCraft releasing soon!'
|
101
109
|
}
|
102
110
|
end
|
103
111
|
|
104
112
|
it "should convert to to_json" do
|
105
113
|
post = build_post_with_comment
|
106
|
-
|
107
|
-
|
108
|
-
post.should_receive(:
|
114
|
+
hash = mock
|
115
|
+
hash.should_receive(:to_json).and_return(:ok)
|
116
|
+
post.should_receive(:to_rson).with(only: :text).and_return(hash)
|
109
117
|
post.to_json(only: :text).should == :ok
|
110
118
|
end
|
111
119
|
|
112
120
|
it "should convert to to_xml" do
|
113
121
|
post = build_post_with_comment
|
114
|
-
|
115
|
-
|
116
|
-
post.should_receive(:
|
122
|
+
hash = mock
|
123
|
+
hash.should_receive(:to_xml).and_return(:ok)
|
124
|
+
post.should_receive(:to_rson).with(only: :text).and_return(hash)
|
117
125
|
post.to_xml(only: :text).should == :ok
|
118
126
|
end
|
119
127
|
end
|
data/spec/crud_spec.rb
CHANGED
@@ -20,6 +20,25 @@ describe "Model CRUD" do
|
|
20
20
|
end
|
21
21
|
after{remove_constants :Unit}
|
22
22
|
|
23
|
+
it 'save should return true or false' do
|
24
|
+
# Successfull create and update.
|
25
|
+
unit = Unit.new
|
26
|
+
unit.save.class.should == TrueClass
|
27
|
+
unit.name = 'Another'
|
28
|
+
unit.save.class.should == TrueClass
|
29
|
+
|
30
|
+
# Invalid create.
|
31
|
+
unit = Unit.new
|
32
|
+
unit.stub!(:valid?).and_return false
|
33
|
+
unit.save.class.should == FalseClass
|
34
|
+
|
35
|
+
# Invalid update.
|
36
|
+
unit = Unit.new
|
37
|
+
unit.save.should be_true
|
38
|
+
unit.stub!(:valid?).and_return false
|
39
|
+
unit.save.class.should == FalseClass
|
40
|
+
end
|
41
|
+
|
23
42
|
it 'should perform CRUD' do
|
24
43
|
# Read.
|
25
44
|
Unit.count.should == 0
|
@@ -77,10 +96,7 @@ describe "Model CRUD" do
|
|
77
96
|
|
78
97
|
it 'should create model' do
|
79
98
|
u = Unit.create(name: 'Zeratul')
|
80
|
-
u.
|
81
|
-
|
82
|
-
u = Unit.create!(name: 'Zeratul')
|
83
|
-
u.new_record?.should be_false
|
99
|
+
u.new?.should be_false
|
84
100
|
end
|
85
101
|
|
86
102
|
it 'should delete all models' do
|
data/spec/misc_spec.rb
CHANGED
@@ -11,10 +11,10 @@ describe 'Miscellaneous' do
|
|
11
11
|
attr_accessor :name
|
12
12
|
end
|
13
13
|
end
|
14
|
-
after{remove_constants :
|
14
|
+
after{remove_constants :Unit, :User}
|
15
15
|
|
16
16
|
it "should create timestamps" do
|
17
|
-
class
|
17
|
+
class Unit
|
18
18
|
inherit Mongo::Model
|
19
19
|
collection :units
|
20
20
|
|
@@ -23,10 +23,10 @@ describe 'Miscellaneous' do
|
|
23
23
|
timestamps!
|
24
24
|
end
|
25
25
|
|
26
|
-
unit =
|
26
|
+
unit = Unit.build name: 'Zeratul'
|
27
27
|
unit.save!
|
28
28
|
|
29
|
-
unit =
|
29
|
+
unit = Unit.first
|
30
30
|
unit.created_at.should_not be_nil
|
31
31
|
unit.updated_at.should_not be_nil
|
32
32
|
created_at,updated_at = unit.created_at, unit.updated_at
|
@@ -37,10 +37,10 @@ describe 'Miscellaneous' do
|
|
37
37
|
end
|
38
38
|
|
39
39
|
it 'should have cache' do
|
40
|
-
class
|
40
|
+
class Unit
|
41
41
|
inherit Mongo::Model
|
42
42
|
end
|
43
|
-
u =
|
43
|
+
u = Unit.new
|
44
44
|
u._cache.should == {}
|
45
45
|
end
|
46
46
|
|
@@ -64,4 +64,45 @@ describe 'Miscellaneous' do
|
|
64
64
|
u.reload
|
65
65
|
u.name.should == 'Zeratul'
|
66
66
|
end
|
67
|
+
|
68
|
+
describe 'original' do
|
69
|
+
before do
|
70
|
+
class Unit
|
71
|
+
inherit Mongo::Model
|
72
|
+
collection :units
|
73
|
+
|
74
|
+
attr_accessor :name
|
75
|
+
end
|
76
|
+
|
77
|
+
@unit = Unit.new.tap{|u| u.name = "Zeratul"}
|
78
|
+
end
|
79
|
+
after{remove_constants :Unit}
|
80
|
+
|
81
|
+
it "should query original from database" do
|
82
|
+
@unit.original.should be_nil
|
83
|
+
@unit.save!
|
84
|
+
|
85
|
+
unit = Unit.first
|
86
|
+
unit.name = "Tassadar"
|
87
|
+
|
88
|
+
Unit.should_receive(:first).with(_id: unit._id).and_return{db.units.first(_id: unit._id)}
|
89
|
+
unit.original.name.should == "Zeratul"
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should use identity map if provided" do
|
93
|
+
Unit.inherit Mongo::Model::IdentityMap
|
94
|
+
|
95
|
+
@unit.original.should be_nil
|
96
|
+
@unit.save!
|
97
|
+
|
98
|
+
Unit.identity_map.size.should == 0
|
99
|
+
unit = Unit.first
|
100
|
+
Unit.identity_map.size.should == 1
|
101
|
+
|
102
|
+
unit.name = "Tassadar"
|
103
|
+
|
104
|
+
Unit.should_not_receive :first
|
105
|
+
unit.original.name.should == "Zeratul"
|
106
|
+
end
|
107
|
+
end
|
67
108
|
end
|
data/spec/query_spec.rb
CHANGED
@@ -74,7 +74,9 @@ describe "Query" do
|
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
-
|
77
|
+
u = SpecialUnit.query(name: 'Zeratul').build status: 'active'
|
78
|
+
u.status.should be_nil
|
79
|
+
|
78
80
|
u = SpecialUnit.query(name: 'Zeratul', status: 'active').build age: 500
|
79
81
|
u.status.should == 'active'
|
80
82
|
end
|
data/spec/validation_spec.rb
CHANGED
@@ -142,4 +142,26 @@ describe "Validation" do
|
|
142
142
|
unit.should be_valid
|
143
143
|
end
|
144
144
|
end
|
145
|
+
|
146
|
+
context "database exceptions" do
|
147
|
+
before do
|
148
|
+
class Unit
|
149
|
+
inherit Mongo::Model
|
150
|
+
collection :units
|
151
|
+
|
152
|
+
attr_accessor :name
|
153
|
+
end
|
154
|
+
end
|
155
|
+
after{remove_constants :Unit}
|
156
|
+
|
157
|
+
it "should convert unique index exception to errors" do
|
158
|
+
db.units.create_index [["name", 1]], unique: true
|
159
|
+
|
160
|
+
Unit.create name: 'Zeratul'
|
161
|
+
|
162
|
+
unit = Unit.new name: 'Zeratul'
|
163
|
+
unit.save.should be_false
|
164
|
+
unit.errors[:base].should == ["not unique value!"]
|
165
|
+
end
|
166
|
+
end
|
145
167
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongodb_model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-12-19 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: mongodb
|
16
|
-
requirement: &
|
16
|
+
requirement: &70169713604240 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70169713604240
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: validatable2
|
27
|
-
requirement: &
|
27
|
+
requirement: &70169713603760 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70169713603760
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: ruby_ext
|
38
|
-
requirement: &
|
38
|
+
requirement: &70169713603260 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70169713603260
|
47
47
|
description:
|
48
48
|
email:
|
49
49
|
executables: []
|
@@ -58,7 +58,10 @@ files:
|
|
58
58
|
- lib/mongo/model/conversion.rb
|
59
59
|
- lib/mongo/model/crud.rb
|
60
60
|
- lib/mongo/model/db.rb
|
61
|
+
- lib/mongo/model/identity_map.rb
|
61
62
|
- lib/mongo/model/integration/file_model.rb
|
63
|
+
- lib/mongo/model/integration/rad/tasks.rb
|
64
|
+
- lib/mongo/model/integration/rad.rb
|
62
65
|
- lib/mongo/model/integration/rails.rb
|
63
66
|
- lib/mongo/model/integration/validatable/uniqueness_validator.rb
|
64
67
|
- lib/mongo/model/integration/validatable.rb
|
@@ -70,7 +73,7 @@ files:
|
|
70
73
|
- lib/mongo/model/scope.rb
|
71
74
|
- lib/mongo/model/spec.rb
|
72
75
|
- lib/mongo/model/support/conversions.rb
|
73
|
-
- lib/mongo/model/support.rb
|
76
|
+
- lib/mongo/model/support/rson.rb
|
74
77
|
- lib/mongo/model/validation.rb
|
75
78
|
- lib/mongo/model.rb
|
76
79
|
- lib/mongodb_model/gems.rb
|
@@ -109,7 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
109
112
|
version: '0'
|
110
113
|
requirements: []
|
111
114
|
rubyforge_project:
|
112
|
-
rubygems_version: 1.8.
|
115
|
+
rubygems_version: 1.8.10
|
113
116
|
signing_key:
|
114
117
|
specification_version: 3
|
115
118
|
summary: Object Model for MongoDB
|
data/lib/mongo/model/support.rb
DELETED