mongodb_model 0.0.10 → 0.0.11
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/lib/mongo/model.rb +2 -1
- data/lib/mongo/model/assignment.rb +25 -28
- data/lib/mongo/model/conversion.rb +67 -0
- data/lib/mongo/model/crud.rb +8 -0
- data/lib/mongo/model/misc.rb +0 -7
- data/lib/mongo/model/model.rb +2 -2
- data/lib/mongo/model/query_mixin.rb +3 -2
- data/lib/mongo/model/scope.rb +13 -0
- data/lib/mongodb_model/gems.rb +1 -1
- data/spec/assignment_spec.rb +2 -1
- data/spec/callbacks_spec.rb +1 -1
- data/spec/conversion_spec.rb +101 -0
- data/spec/crud_spec.rb +12 -0
- data/spec/scope_spec.rb +14 -0
- metadata +12 -21
data/lib/mongo/model.rb
CHANGED
@@ -2,7 +2,6 @@ require 'mongodb_model/gems'
|
|
2
2
|
|
3
3
|
require 'validatable'
|
4
4
|
require 'file_model'
|
5
|
-
require 'i18n'
|
6
5
|
require 'ruby_ext'
|
7
6
|
require 'mongo/object'
|
8
7
|
|
@@ -12,6 +11,7 @@ module Mongo::Model; end
|
|
12
11
|
support/types
|
13
12
|
|
14
13
|
db
|
14
|
+
conversion
|
15
15
|
assignment
|
16
16
|
callbacks
|
17
17
|
validation
|
@@ -30,6 +30,7 @@ module Mongo
|
|
30
30
|
module Model
|
31
31
|
inherit \
|
32
32
|
Db,
|
33
|
+
Conversion,
|
33
34
|
Assignment,
|
34
35
|
Callbacks,
|
35
36
|
Validation,
|
@@ -1,32 +1,13 @@
|
|
1
1
|
module Mongo::Model::Assignment
|
2
2
|
class Dsl < BasicObject
|
3
|
-
def initialize
|
4
|
-
@
|
3
|
+
def initialize model
|
4
|
+
@model = model
|
5
5
|
end
|
6
6
|
|
7
|
-
def self.const_missing name
|
8
|
-
# BasicObject doesn't have access to any constants like String, Symbol, ...
|
9
|
-
::Object.const_get name
|
10
|
-
end
|
11
|
-
|
12
|
-
def to_h; attributes end
|
13
|
-
|
14
7
|
protected
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
attribute_name.must_be.a Symbol
|
19
|
-
|
20
|
-
args.size.must_be.in 1..2
|
21
|
-
if args.first.is_a? Class
|
22
|
-
type, mass_assignment = args
|
23
|
-
mass_assignment ||= false
|
24
|
-
type.must.respond_to :cast
|
25
|
-
else
|
26
|
-
type, mass_assignment = nil, args.first
|
27
|
-
end
|
28
|
-
|
29
|
-
attributes[attribute_name] = [type, mass_assignment]
|
8
|
+
def method_missing m, *args
|
9
|
+
args.unshift m
|
10
|
+
@model.assign *args
|
30
11
|
end
|
31
12
|
end
|
32
13
|
|
@@ -61,10 +42,26 @@ module Mongo::Model::Assignment
|
|
61
42
|
module ClassMethods
|
62
43
|
inheritable_accessor :_assign, nil
|
63
44
|
|
64
|
-
def assign &block
|
65
|
-
|
66
|
-
|
67
|
-
|
45
|
+
def assign *args, &block
|
46
|
+
if block
|
47
|
+
dsl = ::Mongo::Model::Assignment::Dsl.new self
|
48
|
+
dsl.instance_eval &block
|
49
|
+
else
|
50
|
+
args.size.must_be.in 2..3
|
51
|
+
attr_name = args.shift
|
52
|
+
attr_name.must_be.a Symbol
|
53
|
+
|
54
|
+
if args.first.is_a? Class
|
55
|
+
type, mass_assignment = args
|
56
|
+
mass_assignment ||= false
|
57
|
+
type.must.respond_to :cast
|
58
|
+
else
|
59
|
+
type, mass_assignment = nil, args.first
|
60
|
+
end
|
61
|
+
|
62
|
+
self._assign ||= {}
|
63
|
+
_assign[attr_name] = [type, mass_assignment]
|
64
|
+
end
|
68
65
|
end
|
69
66
|
end
|
70
67
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Mongo::Model::Conversion
|
2
|
+
def model_to_json *args, &block
|
3
|
+
to_rson(*args, &block).to_json
|
4
|
+
end
|
5
|
+
|
6
|
+
def model_to_xml *args, &block
|
7
|
+
to_rson(*args, &block).to_xml
|
8
|
+
end
|
9
|
+
|
10
|
+
alias_method :to_json, :model_to_json
|
11
|
+
alias_method :to_xml, :model_to_xml
|
12
|
+
|
13
|
+
inherited do
|
14
|
+
alias_method :to_json, :model_to_json
|
15
|
+
alias_method :to_xml, :model_to_xml
|
16
|
+
|
17
|
+
# hack to supress ActiveSupport as_json
|
18
|
+
alias_method :as_json, :model_to_json
|
19
|
+
alias_method :as_xml, :model_to_xml
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_rson options = {}
|
23
|
+
# hack to suppress ActiveSupport as_json
|
24
|
+
options ||= {}
|
25
|
+
|
26
|
+
if profile = options[:profile]
|
27
|
+
raise "no other optins are allowed when using :profile option!" if options.size > 1
|
28
|
+
profile_options = self.class.profiles[profile] || raise("profile :#{profile} not defined for #{self.class}!")
|
29
|
+
to_rson profile_options.merge(_profile: profile)
|
30
|
+
else
|
31
|
+
options.validate_options! :only, :except, :methods, :_profile
|
32
|
+
child_options = options[:_profile] ? {profile: options[:_profile]} : {}
|
33
|
+
|
34
|
+
instance_variables = Mongo::Object.instance_variables(self)
|
35
|
+
|
36
|
+
if only = options[:only]
|
37
|
+
instance_variables &= Array(only).collect{|n| :"@#{n}"}
|
38
|
+
elsif except = options[:except]
|
39
|
+
instance_variables -= Array(except).collect{|n| :"@#{n}"}
|
40
|
+
end
|
41
|
+
|
42
|
+
result = {}
|
43
|
+
instance_variables.each do |iv_name|
|
44
|
+
value = instance_variable_get iv_name
|
45
|
+
value = Mongo::Object.convert value, :to_rson, child_options
|
46
|
+
result[iv_name[1.. -1]] = value
|
47
|
+
end
|
48
|
+
|
49
|
+
methods = options[:methods] ? Array(options[:methods]) : []
|
50
|
+
|
51
|
+
methods.each do |method|
|
52
|
+
value = send method
|
53
|
+
value = Mongo::Object.convert value, :to_rson, child_options
|
54
|
+
result[method.to_s] = value
|
55
|
+
end
|
56
|
+
|
57
|
+
result
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
module ClassMethods
|
62
|
+
inheritable_accessor :profiles, {}
|
63
|
+
def profile name, options = {}
|
64
|
+
profiles[name] = options
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/mongo/model/crud.rb
CHANGED
@@ -19,6 +19,10 @@ module Mongo::Model::Crud
|
|
19
19
|
destroy(*args) || raise(Mongo::Error, "can't destroy invalid model #{self.errors}!")
|
20
20
|
end
|
21
21
|
|
22
|
+
def update doc, options = {}
|
23
|
+
self.class.collection.update({_id: _id}, doc, options)
|
24
|
+
end
|
25
|
+
|
22
26
|
module ClassMethods
|
23
27
|
def build attributes = {}, options = {}, &block
|
24
28
|
model = self.new
|
@@ -49,6 +53,10 @@ module Mongo::Model::Crud
|
|
49
53
|
def destroy_all! selector = {}, options = {}
|
50
54
|
destroy_all(selector, options) || raise(Mongo::Error, "can't destroy #{selector.inspect}!")
|
51
55
|
end
|
56
|
+
|
57
|
+
def update selector, doc, options = {}
|
58
|
+
collection.update selector, doc, options
|
59
|
+
end
|
52
60
|
end
|
53
61
|
|
54
62
|
protected
|
data/lib/mongo/model/misc.rb
CHANGED
@@ -12,9 +12,6 @@ module Mongo::Model::Misc
|
|
12
12
|
def _cache
|
13
13
|
@_cache ||= {}
|
14
14
|
end
|
15
|
-
# def _clear_cache
|
16
|
-
# @_cache = {}
|
17
|
-
# end
|
18
15
|
|
19
16
|
def dom_id
|
20
17
|
# new_record? ? "new_#{self.class.name.underscore}" : to_param
|
@@ -25,8 +22,6 @@ module Mongo::Model::Misc
|
|
25
22
|
(_id || '').to_s
|
26
23
|
end
|
27
24
|
|
28
|
-
delegate :t, to: I18n
|
29
|
-
|
30
25
|
def reload
|
31
26
|
obj = self.class.by_id!(_id || raise("can't reload new document (#{self})!"))
|
32
27
|
instance_variables.each{|n| remove_instance_variable n}
|
@@ -41,8 +36,6 @@ module Mongo::Model::Misc
|
|
41
36
|
end
|
42
37
|
|
43
38
|
module ClassMethods
|
44
|
-
delegate :t, to: I18n
|
45
|
-
|
46
39
|
def timestamps!
|
47
40
|
attr_accessor :created_at, :updated_at
|
48
41
|
before_create :update_created_at
|
data/lib/mongo/model/model.rb
CHANGED
@@ -19,8 +19,8 @@ module Mongo::Model
|
|
19
19
|
def model_eq? o
|
20
20
|
return true if equal? o
|
21
21
|
|
22
|
-
variables = {}; ::Mongo::Object.
|
23
|
-
o_variables = {}; ::Mongo::Object.
|
22
|
+
variables = {}; ::Mongo::Object.each_instance_variable(self){|n, v| variables[n] = v}
|
23
|
+
o_variables = {}; ::Mongo::Object.each_instance_variable(o){|n, v| o_variables[n] = v}
|
24
24
|
|
25
25
|
variables == o_variables
|
26
26
|
end
|
@@ -2,7 +2,7 @@ module Mongo::Model::QueryMixin
|
|
2
2
|
def exists? options = {}
|
3
3
|
self.class.count({_id: _id}, options) > 0
|
4
4
|
end
|
5
|
-
|
5
|
+
alias_method :exist?, :exists?
|
6
6
|
|
7
7
|
module ClassMethods
|
8
8
|
include Mongo::DynamicFinders
|
@@ -36,7 +36,7 @@ module Mongo::Model::QueryMixin
|
|
36
36
|
def exists? selector = {}, options = {}
|
37
37
|
count(selector, options) > 0
|
38
38
|
end
|
39
|
-
|
39
|
+
alias_method :exist?, :exists?
|
40
40
|
|
41
41
|
def query *args
|
42
42
|
if args.first.is_a? Mongo::Model::Query
|
@@ -46,5 +46,6 @@ module Mongo::Model::QueryMixin
|
|
46
46
|
Mongo::Model::Query.new self, (selector || {}), (options || {})
|
47
47
|
end
|
48
48
|
end
|
49
|
+
alias_method :where, :query
|
49
50
|
end
|
50
51
|
end
|
data/lib/mongo/model/scope.rb
CHANGED
@@ -81,6 +81,19 @@ module Mongo::Model::Scope
|
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
|
+
|
85
|
+
#
|
86
|
+
# Handy scopes
|
87
|
+
#
|
88
|
+
def limit n; query({}, limit: n) end
|
89
|
+
def skip n; query({}, skip: n) end
|
90
|
+
def sort *list; query({}, sort: list) end
|
91
|
+
def snapshot; query({}, snapshot: true) end
|
92
|
+
|
93
|
+
def paginate page, per_page
|
94
|
+
skip((page - 1) * per_page).limit(per_page)
|
95
|
+
end
|
96
|
+
|
84
97
|
protected
|
85
98
|
def scope_identifier
|
86
99
|
@scope_identifier ||= :"mms_#{self.name}"
|
data/lib/mongodb_model/gems.rb
CHANGED
data/spec/assignment_spec.rb
CHANGED
data/spec/callbacks_spec.rb
CHANGED
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Model callbacks' do
|
4
|
+
with_mongo_model
|
5
|
+
|
6
|
+
before :all do
|
7
|
+
class BasePost
|
8
|
+
inherit Mongo::Model
|
9
|
+
|
10
|
+
attr_accessor :text, :token
|
11
|
+
|
12
|
+
attr_writer :comments
|
13
|
+
def comments; @comments ||= [] end
|
14
|
+
|
15
|
+
def teaser
|
16
|
+
@text && @text[0..10]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class BaseComment
|
21
|
+
inherit Mongo::Model
|
22
|
+
|
23
|
+
attr_accessor :text
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
before do
|
28
|
+
class Post < BasePost; end
|
29
|
+
class Comment < BaseComment; end
|
30
|
+
end
|
31
|
+
|
32
|
+
after{remove_constants :Post, :Comment}
|
33
|
+
after(:all){remove_constants :BasePost, :BaseComment}
|
34
|
+
|
35
|
+
def build_post_with_comment
|
36
|
+
post = Post.new text: 'StarCraft releasing soon!', token: 'secret'
|
37
|
+
post.comments << Comment.new(text: 'Cool!')
|
38
|
+
post
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should work without arguments" do
|
42
|
+
post = build_post_with_comment
|
43
|
+
post.to_rson.should == {
|
44
|
+
'text' => 'StarCraft releasing soon!',
|
45
|
+
'token' => 'secret',
|
46
|
+
'comments' => [
|
47
|
+
{'text' => 'Cool!'}
|
48
|
+
]
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
it "only, except, methods" do
|
53
|
+
post = build_post_with_comment
|
54
|
+
post.to_rson(only: :text).should == {'text' => 'StarCraft releasing soon!'}
|
55
|
+
post.to_rson(except: :token).should == {
|
56
|
+
'text' => 'StarCraft releasing soon!',
|
57
|
+
'comments' => [
|
58
|
+
{'text' => 'Cool!'}
|
59
|
+
]
|
60
|
+
}
|
61
|
+
post.to_rson(only: [], methods: :teaser).should == {'teaser' => 'StarCraft r'}
|
62
|
+
end
|
63
|
+
|
64
|
+
it "profiles" do
|
65
|
+
Post.class_eval do
|
66
|
+
profile :public, only: [:text, :comments], methods: :teaser
|
67
|
+
end
|
68
|
+
|
69
|
+
post = build_post_with_comment
|
70
|
+
|
71
|
+
-> {post.to_rson(profile: :public)}.should raise_error(/profile :public not defined for Comment/)
|
72
|
+
|
73
|
+
Comment.class_eval do
|
74
|
+
profile :public
|
75
|
+
end
|
76
|
+
|
77
|
+
post.to_rson(profile: :public).should == {
|
78
|
+
'text' => 'StarCraft releasing soon!',
|
79
|
+
'teaser' => 'StarCraft r',
|
80
|
+
'comments' => [
|
81
|
+
{'text' => 'Cool!'}
|
82
|
+
]
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
it "to_json" do
|
87
|
+
post = build_post_with_comment
|
88
|
+
rson = mock
|
89
|
+
rson.should_receive(:to_json).and_return(:ok)
|
90
|
+
post.should_receive(:to_rson).with(only: :text).and_return(rson)
|
91
|
+
post.to_json(only: :text).should == :ok
|
92
|
+
end
|
93
|
+
|
94
|
+
it "to_xml" do
|
95
|
+
post = build_post_with_comment
|
96
|
+
rson = mock
|
97
|
+
rson.should_receive(:to_xml).and_return(:ok)
|
98
|
+
post.should_receive(:to_rson).with(only: :text).and_return(rson)
|
99
|
+
post.to_xml(only: :text).should == :ok
|
100
|
+
end
|
101
|
+
end
|
data/spec/crud_spec.rb
CHANGED
@@ -93,6 +93,18 @@ describe "Model CRUD" do
|
|
93
93
|
|
94
94
|
Unit.destroy_all!
|
95
95
|
end
|
96
|
+
|
97
|
+
it 'modifiers' do
|
98
|
+
unit = Unit.create! name: 'Zeratul'
|
99
|
+
|
100
|
+
Unit.update({_id: unit._id}, _set: {name: 'Tassadar'})
|
101
|
+
unit.reload
|
102
|
+
unit.name.should == 'Tassadar'
|
103
|
+
|
104
|
+
unit.update _set: {name: 'Fenix'}
|
105
|
+
unit.reload
|
106
|
+
unit.name.should == 'Fenix'
|
107
|
+
end
|
96
108
|
end
|
97
109
|
|
98
110
|
describe 'embedded' do
|
data/spec/scope_spec.rb
CHANGED
@@ -147,4 +147,18 @@ describe "Scope" do
|
|
147
147
|
end
|
148
148
|
end
|
149
149
|
end
|
150
|
+
|
151
|
+
describe 'handy scopes' do
|
152
|
+
it "limit, skip, sort" do
|
153
|
+
query = Unit.skip(30).limit(10).sort([name: 1]).snapshot
|
154
|
+
query.selector.should == {}
|
155
|
+
query.options.should == {skip: 30, limit: 10, sort: [[name: 1]], snapshot: true}
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'paginate' do
|
159
|
+
query = Unit.paginate(4, 10)
|
160
|
+
query.selector.should == {}
|
161
|
+
query.options.should == {skip: 30, limit: 10}
|
162
|
+
end
|
163
|
+
end
|
150
164
|
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: 0.0.
|
4
|
+
version: 0.0.11
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,22 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-09-
|
12
|
+
date: 2011-09-06 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
|
-
- !ruby/object:Gem::Dependency
|
15
|
-
name: i18n
|
16
|
-
requirement: &2781050 !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
|
-
requirements:
|
19
|
-
- - ~>
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: '0.5'
|
22
|
-
type: :runtime
|
23
|
-
prerelease: false
|
24
|
-
version_requirements: *2781050
|
25
14
|
- !ruby/object:Gem::Dependency
|
26
15
|
name: mongodb
|
27
|
-
requirement: &
|
16
|
+
requirement: &2839010 !ruby/object:Gem::Requirement
|
28
17
|
none: false
|
29
18
|
requirements:
|
30
19
|
- - ! '>='
|
@@ -32,10 +21,10 @@ dependencies:
|
|
32
21
|
version: '0'
|
33
22
|
type: :runtime
|
34
23
|
prerelease: false
|
35
|
-
version_requirements: *
|
24
|
+
version_requirements: *2839010
|
36
25
|
- !ruby/object:Gem::Dependency
|
37
26
|
name: file_model
|
38
|
-
requirement: &
|
27
|
+
requirement: &2845520 !ruby/object:Gem::Requirement
|
39
28
|
none: false
|
40
29
|
requirements:
|
41
30
|
- - ! '>='
|
@@ -43,10 +32,10 @@ dependencies:
|
|
43
32
|
version: '0'
|
44
33
|
type: :runtime
|
45
34
|
prerelease: false
|
46
|
-
version_requirements: *
|
35
|
+
version_requirements: *2845520
|
47
36
|
- !ruby/object:Gem::Dependency
|
48
37
|
name: validatable2
|
49
|
-
requirement: &
|
38
|
+
requirement: &2846710 !ruby/object:Gem::Requirement
|
50
39
|
none: false
|
51
40
|
requirements:
|
52
41
|
- - ! '>='
|
@@ -54,10 +43,10 @@ dependencies:
|
|
54
43
|
version: '0'
|
55
44
|
type: :runtime
|
56
45
|
prerelease: false
|
57
|
-
version_requirements: *
|
46
|
+
version_requirements: *2846710
|
58
47
|
- !ruby/object:Gem::Dependency
|
59
48
|
name: ruby_ext
|
60
|
-
requirement: &
|
49
|
+
requirement: &2847870 !ruby/object:Gem::Requirement
|
61
50
|
none: false
|
62
51
|
requirements:
|
63
52
|
- - ! '>='
|
@@ -65,7 +54,7 @@ dependencies:
|
|
65
54
|
version: '0'
|
66
55
|
type: :runtime
|
67
56
|
prerelease: false
|
68
|
-
version_requirements: *
|
57
|
+
version_requirements: *2847870
|
69
58
|
description:
|
70
59
|
email:
|
71
60
|
executables: []
|
@@ -77,6 +66,7 @@ files:
|
|
77
66
|
- lib/mongo/model/assignment.rb
|
78
67
|
- lib/mongo/model/attribute_convertors.rb
|
79
68
|
- lib/mongo/model/callbacks.rb
|
69
|
+
- lib/mongo/model/conversion.rb
|
80
70
|
- lib/mongo/model/crud.rb
|
81
71
|
- lib/mongo/model/db.rb
|
82
72
|
- lib/mongo/model/file_model.rb
|
@@ -95,6 +85,7 @@ files:
|
|
95
85
|
- spec/associations_spec.rb
|
96
86
|
- spec/attribute_convertors_spec.rb
|
97
87
|
- spec/callbacks_spec.rb
|
88
|
+
- spec/conversion_spec.rb
|
98
89
|
- spec/crud_spec.rb
|
99
90
|
- spec/db_spec.rb
|
100
91
|
- spec/equality_spec.rb
|