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 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