mongodb_model 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
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
- @attributes = {}
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
- attr_reader :attributes
16
-
17
- def method_missing attribute_name, *args
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
- dsl = ::Mongo::Model::Assignment::Dsl.new
66
- dsl.instance_eval &block
67
- self._assign = (_assign || {}).merge dsl.to_h
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
@@ -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
@@ -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
@@ -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.each_object_instance_variable(self){|n, v| variables[n] = v}
23
- o_variables = {}; ::Mongo::Object.each_object_instance_variable(o){|n, v| o_variables[n] = v}
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
- alias :exist? :exists?
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
- alias :exist? :exists?
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
@@ -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}"
@@ -1,4 +1,4 @@
1
- gem 'i18n', '~> 0.5'
1
+ # gem 'i18n', '~> 0.5'
2
2
 
3
3
  if respond_to? :fake_gem
4
4
  fake_gem 'mongodb'
@@ -23,8 +23,9 @@ describe 'Model callbacks' do
23
23
 
24
24
  attr_accessor :name, :has_mail, :age, :position, :banned
25
25
 
26
+ assign :name, String, true
27
+
26
28
  assign do
27
- name String, true
28
29
  has_mail Boolean, true
29
30
  end
30
31
 
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  describe 'Model callbacks' do
4
4
  with_mongo_model
5
5
 
6
- after(:all){remove_constants :TheModel, :Player}
6
+ after{remove_constants :TheModel, :Player}
7
7
 
8
8
  it "integration smoke test" do
9
9
  class Player
@@ -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.10
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-04 00:00:00.000000000Z
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: &2780760 !ruby/object:Gem::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: *2780760
24
+ version_requirements: *2839010
36
25
  - !ruby/object:Gem::Dependency
37
26
  name: file_model
38
- requirement: &2780460 !ruby/object:Gem::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: *2780460
35
+ version_requirements: *2845520
47
36
  - !ruby/object:Gem::Dependency
48
37
  name: validatable2
49
- requirement: &2780160 !ruby/object:Gem::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: *2780160
46
+ version_requirements: *2846710
58
47
  - !ruby/object:Gem::Dependency
59
48
  name: ruby_ext
60
- requirement: &2779870 !ruby/object:Gem::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: *2779870
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