mongodb_model 2.1.1 → 2.1.2

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.
@@ -21,13 +21,14 @@ module Mongo::Model::Conversion
21
21
  alias_method :as_xml, :model_to_xml
22
22
  end
23
23
 
24
- def to_rson options = {}
24
+ def to_rson options = {}, &block
25
25
  options = {profile: options} if options.is_a? Symbol
26
26
 
27
27
  if profile = options[:profile]
28
28
  raise "no other optins are allowed when using :profile option!" if options.size > 1
29
- profile_options = self.class.profiles[profile] || raise("profile :#{profile} not defined for #{self.class}!")
30
- to_rson profile_options.merge(_profile: profile)
29
+ meta = self.class.profiles[profile] || raise("profile :#{profile} not defined for #{self.class}!")
30
+ profile_options, profile_block = meta
31
+ to_rson profile_options.merge(_profile: profile), &profile_block
31
32
  else
32
33
  options.validate_options! :only, :except, :methods, :errors, :id, :_profile
33
34
  child_options = options[:_profile] ? {profile: options[:_profile]} : {}
@@ -61,7 +62,9 @@ module Mongo::Model::Conversion
61
62
  result[:errors] = errors
62
63
  end
63
64
 
64
- result[:id] = _id if _id and (options[:id] != false)
65
+ result[:id] = id if id and (options[:id] != false)
66
+
67
+ instance_exec result, &block if block
65
68
 
66
69
  result
67
70
  end
@@ -69,8 +72,8 @@ module Mongo::Model::Conversion
69
72
 
70
73
  module ClassMethods
71
74
  inheritable_accessor :profiles, {}
72
- def profile name, options = {}
73
- profiles[name] = options
75
+ def profile name, options = {}, &block
76
+ profiles[name] = [options, block]
74
77
  end
75
78
  end
76
79
  end
@@ -46,7 +46,7 @@ module Mongo::Model::Crud
46
46
 
47
47
  def update doc, options = {}
48
48
  with_collection options do |collection, options|
49
- collection.update({_id: _id}, doc, options)
49
+ collection.update({id: id}, doc, options)
50
50
  end
51
51
  end
52
52
 
@@ -104,7 +104,10 @@ module Mongo::Model::Crud
104
104
  protected
105
105
  def with_collection options, &block
106
106
  options = options.clone
107
- collection = options.delete(:collection) || self.class.collection
107
+ if collection = options.delete(:collection)
108
+ collection = self.class.db.collection collection if collection.is_a?(Symbol)
109
+ end
110
+ collection ||= self.class.collection
108
111
  block.call collection, options
109
112
  end
110
113
  end
@@ -6,7 +6,7 @@ module Mongo::Model::IdentityMap
6
6
  def original
7
7
  unless _cache[:original_cached]
8
8
  _cache[:original_cached] = true
9
- _cache[:original] = _id && self.class.get_from_identity_map(_id)
9
+ _cache[:original] = id && self.class.get_from_identity_map(id)
10
10
  end
11
11
  _cache[:original]
12
12
  end
@@ -23,7 +23,7 @@ module Mongo::Model::IdentityMap
23
23
 
24
24
  def from_mongo doc
25
25
  model = super doc
26
- model.class.identity_map[model._id] = doc if model._id
26
+ model.class.identity_map[model.id] = doc if model.id
27
27
  model
28
28
  end
29
29
  end
@@ -12,7 +12,33 @@ rad.register :models do
12
12
  Mongo::Model::Component.new
13
13
  end
14
14
 
15
- # Using DB connection setting defined in component's config file.
15
+ # Connection settings defined in the `models.yml` config file for the :models component.
16
+ #
17
+ # Sample of `models.yml` config file, it cotains database names and connection settings.
18
+ #
19
+ # db:
20
+ # default:
21
+ # host: localhost
22
+ # port: 4029
23
+ # name: my_web_app
24
+ # tmp:
25
+ # name: all_sorts_of_tmp_data
26
+ #
27
+ # Note that we use logical name of the database, the real name can be different. It gives You flexibility and
28
+ # allows You to use the same logical name, but it can mean different databases with different real names in
29
+ # let's say :development and :production evnironments:
30
+ #
31
+ # Usage - if not specified the :default alias will be used:
32
+ #
33
+ # class Blog
34
+ # end
35
+ #
36
+ # You can also explicitly specify what alias should be used:
37
+ #
38
+ # class Token
39
+ # db :tmp
40
+ # end
41
+ #
16
42
  Mongo.metaclass_eval do
17
43
  def db name
18
44
  config = rad.models.db[name.to_s] || raise("no database config for #{name} alias!")
@@ -14,10 +14,10 @@ end
14
14
  module Mongo::Model::Rails
15
15
  def to_model; self end
16
16
 
17
- def persisted?; !!_id end
17
+ def persisted?; _saved end
18
18
 
19
19
  def to_key
20
- persisted? ? [_id] : nil
20
+ persisted? ? [id] : nil
21
21
  end
22
22
 
23
23
  def new_record?; new? end
@@ -19,7 +19,7 @@ class Validatable::UniquenessValidator < Validatable::ValidationBase
19
19
  end
20
20
 
21
21
  # Make sure we're not including the current document in the query.
22
- conditions[:_id] = {_ne: instance._id} if instance._id
22
+ conditions[:_id] = {_ne: instance.id} if instance.id
23
23
 
24
24
  !klass.exists?(conditions)
25
25
  end
@@ -18,11 +18,11 @@ module Mongo::Model::Misc
18
18
  end
19
19
 
20
20
  def to_param
21
- _id.try :to_s
21
+ id.try :to_s
22
22
  end
23
23
 
24
24
  def reload
25
- obj = self.class.by_id!(_id || raise("can't reload new document (#{self})!"))
25
+ obj = self.class.by_id!(id || raise("can't reload new document (#{self})!"))
26
26
  instance_variables.each{|n| remove_instance_variable n}
27
27
  obj.instance_variables.each do |n|
28
28
  instance_variable_set n, obj.instance_variable_get(n)
@@ -33,7 +33,7 @@ module Mongo::Model::Misc
33
33
  def original
34
34
  unless _cache[:original_cached]
35
35
  _cache[:original_cached] = true
36
- _cache[:original] = _id && self.class.by_id(_id)
36
+ _cache[:original] = id && self.class.by_id(id)
37
37
  end
38
38
  _cache[:original]
39
39
  end
@@ -1,6 +1,6 @@
1
1
  module Mongo::Model::QueryMixin
2
2
  def exists? options = {}
3
- self.class.count({_id: _id}, options) > 0
3
+ self.class.count({id: id}, options) > 0
4
4
  end
5
5
  alias_method :exist?, :exists?
6
6
 
@@ -1,113 +1,116 @@
1
- module Mongo::Model::Scope
2
- module ClassMethods
3
- def current_scope
4
- scope, exclusive = Thread.current[scope_identifier]
5
- current = if exclusive
6
- scope
7
- elsif scope
8
- default_scope ? default_scope.merge(scope) : scope
9
- else
10
- default_scope
11
- end
12
- end
1
+ module Mongo::Model
2
+ PER_PAGE, MAX_PER_PAGE = 25, 100
13
3
 
14
- def with_exclusive_scope *args, &block
15
- with_scope *(args << true), &block
16
- end
4
+ module Scope
5
+ module ClassMethods
6
+ def current_scope
7
+ scope, exclusive = Thread.current[scope_identifier]
8
+ current = if exclusive
9
+ scope
10
+ elsif scope
11
+ default_scope ? default_scope.merge(scope) : scope
12
+ else
13
+ default_scope
14
+ end
15
+ end
17
16
 
18
- def with_scope *args, &block
19
- if args.last.is_a?(TrueClass) or args.last.is_a?(FalseClass)
20
- exclusive = args.pop
21
- else
22
- exclusive = false
17
+ def with_exclusive_scope *args, &block
18
+ with_scope *(args << true), &block
23
19
  end
24
20
 
25
- scope = query *args
26
- previous_scope, previous_exclusive = Thread.current[scope_identifier]
27
- raise "exclusive scope already applied!" if previous_exclusive
21
+ def with_scope *args, &block
22
+ if args.last.is_a?(TrueClass) or args.last.is_a?(FalseClass)
23
+ exclusive = args.pop
24
+ else
25
+ exclusive = false
26
+ end
28
27
 
29
- begin
30
- scope = previous_scope.merge scope if !exclusive and previous_scope
31
- Thread.current[scope_identifier] = [scope, exclusive]
32
- return block.call
33
- ensure
34
- Thread.current[scope_identifier] = [previous_scope, false]
28
+ scope = query *args
29
+ previous_scope, previous_exclusive = Thread.current[scope_identifier]
30
+ raise "exclusive scope already applied!" if previous_exclusive
31
+
32
+ begin
33
+ scope = previous_scope.merge scope if !exclusive and previous_scope
34
+ Thread.current[scope_identifier] = [scope, exclusive]
35
+ return block.call
36
+ ensure
37
+ Thread.current[scope_identifier] = [previous_scope, false]
38
+ end
35
39
  end
36
- end
37
40
 
38
- inheritable_accessor :_default_scope, nil
39
- def default_scope *args, &block
40
- if block
41
- self._default_scope = -> {query block.call}
42
- elsif !args.empty?
43
- self._default_scope = -> {query *args}
44
- else
45
- _default_scope && _default_scope.call
41
+ inheritable_accessor :_default_scope, nil
42
+ def default_scope *args, &block
43
+ if block
44
+ self._default_scope = -> {query block.call}
45
+ elsif !args.empty?
46
+ self._default_scope = -> {query *args}
47
+ else
48
+ _default_scope && _default_scope.call
49
+ end
46
50
  end
47
- end
48
51
 
49
- def scope name, *args, &block
50
- model = self
51
- metaclass.define_method name do
52
- query (block && instance_eval(&block)) || args
52
+ def scope name, *args, &block
53
+ model = self
54
+ metaclass.define_method name do
55
+ query (block && instance_eval(&block)) || args
56
+ end
53
57
  end
54
- end
55
58
 
56
- # Finders.
59
+ # Finders.
57
60
 
58
- def count selector = {}, options = {}
59
- if current = current_scope
60
- super current.selector.merge(selector), current.options.merge(options)
61
- else
62
- super selector, options
61
+ def count selector = {}, options = {}
62
+ if current = current_scope
63
+ super current.selector.merge(selector), current.options.merge(options)
64
+ else
65
+ super selector, options
66
+ end
63
67
  end
64
- end
65
68
 
66
- def first selector = {}, options = {}
67
- if current = current_scope
68
- super current.selector.merge(selector), current.options.merge(options)
69
- else
70
- super selector, options
69
+ def first selector = {}, options = {}
70
+ if current = current_scope
71
+ super current.selector.merge(selector), current.options.merge(options)
72
+ else
73
+ super selector, options
74
+ end
71
75
  end
72
- end
73
76
 
74
- def each selector = {}, options = {}, &block
75
- if current = current_scope
76
- super current.selector.merge(selector), current.options.merge(options), &block
77
- else
78
- super selector, options, &block
77
+ def each selector = {}, options = {}, &block
78
+ if current = current_scope
79
+ super current.selector.merge(selector), current.options.merge(options), &block
80
+ else
81
+ super selector, options, &block
82
+ end
79
83
  end
80
- end
81
-
82
- # Shortcuts for frequently used scopes.
83
84
 
84
- def limit n; query({}, limit: n) end
85
- def skip n; query({}, skip: n) end
86
- def sort *list
87
- list = list.collect{|item| item.is_a?(Array) ? item : [item, 1]}
88
- query({}, sort: list)
89
- end
90
- alias_method :sort_by, :sort
91
- def snapshot; query({}, snapshot: true) end
85
+ # Shortcuts for frequently used scopes.
92
86
 
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]
87
+ def limit n; query({}, limit: n) end
88
+ def skip n; query({}, skip: n) end
89
+ def sort *list
90
+ list = list.collect{|item| item.is_a?(Array) ? item : [item, 1]}
91
+ query({}, sort: list)
101
92
  end
102
- page ||= 1
103
- per_page ||= PER_PAGE
104
- per_page = MAX_PER_PAGE if per_page > MAX_PER_PAGE
105
- skip((page - 1) * per_page).limit(per_page)
106
- end
93
+ alias_method :sort_by, :sort
94
+ def snapshot; query({}, snapshot: true) end
107
95
 
108
- protected
109
- def scope_identifier
110
- @scope_identifier ||= :"mms_#{self.name}"
96
+ def paginate *args
97
+ args.size.must.be_in 1..2
98
+ if args.size == 2
99
+ page, per_page = *args
100
+ else
101
+ options = args.first
102
+ page, per_page = options[:page].try(:to_i), options[:per_page].try(:to_i)
103
+ end
104
+ page ||= 1
105
+ per_page ||= PER_PAGE
106
+ per_page = MAX_PER_PAGE if per_page > MAX_PER_PAGE
107
+ skip((page - 1) * per_page).limit(per_page)
111
108
  end
109
+
110
+ protected
111
+ def scope_identifier
112
+ @scope_identifier ||= :"mms_#{self.name}"
113
+ end
114
+ end
112
115
  end
113
116
  end
@@ -13,7 +13,7 @@ describe 'Associations' do
13
13
  attr_accessor :text
14
14
 
15
15
  def comments
16
- Comment.query({post_id: _id}, {sort: [[:text, -1]]})
16
+ Comment.query({post_id: id}, {sort: [[:text, -1]]})
17
17
  end
18
18
  end
19
19
 
@@ -49,11 +49,12 @@ describe 'Conversion' do
49
49
  }
50
50
  end
51
51
 
52
- it "should accept :only, :except and :methods options" do
52
+ it "should accept :only, :except, :methods options and block" do
53
53
  post = build_post_with_comment
54
54
  post.to_rson(only: :text).should == {text: 'StarCraft releasing soon!'}
55
- post.to_rson(except: :token).should == {
55
+ post.to_rson(except: :token){|data| data[:type] = 'Post'}.should == {
56
56
  text: 'StarCraft releasing soon!',
57
+ type: 'Post',
57
58
  comments: [
58
59
  {text: 'Cool!'}
59
60
  ]
@@ -71,14 +72,16 @@ describe 'Conversion' do
71
72
  -> {post.to_rson(profile: :public)}.should raise_error(/profile :public not defined for Comment/)
72
73
 
73
74
  Comment.class_eval do
74
- profile :public
75
+ profile :public do |data|
76
+ data[:type] = 'Comment'
77
+ end
75
78
  end
76
79
 
77
80
  post.to_rson(profile: :public).should == {
78
81
  text: 'StarCraft releasing soon!',
79
82
  teaser: 'StarCraft r',
80
83
  comments: [
81
- {text: 'Cool!'}
84
+ {text: 'Cool!', type: 'Comment'}
82
85
  ]
83
86
  }
84
87
 
@@ -86,7 +89,7 @@ describe 'Conversion' do
86
89
  text: 'StarCraft releasing soon!',
87
90
  teaser: 'StarCraft r',
88
91
  comments: [
89
- {text: 'Cool!'}
92
+ {text: 'Cool!', type: 'Comment'}
90
93
  ]
91
94
  }
92
95
  end
@@ -47,7 +47,7 @@ describe "Model CRUD" do
47
47
 
48
48
  # Create.
49
49
  @unit.save.should be_true
50
- @unit._id.should_not be_nil
50
+ @unit.id.should_not be_nil
51
51
 
52
52
  # Read.
53
53
  Unit.count.should == 1
@@ -69,7 +69,7 @@ describe "Model CRUD" do
69
69
  it 'should be able to save model to another collection' do
70
70
  # Create.
71
71
  @unit.save(collection: db.heroes).should be_true
72
- @unit._id.should_not be_nil
72
+ @unit.id.should_not be_nil
73
73
 
74
74
  # Read.
75
75
  Unit.count.should == 0
@@ -89,6 +89,11 @@ describe "Model CRUD" do
89
89
  db.heroes.count.should == 0
90
90
  end
91
91
 
92
+ it 'should be able to save model to another collection (defined as symbol)' do
93
+ @unit.save(collection: :heroes).should be_true
94
+ db.heroes.first.should == @unit
95
+ end
96
+
92
97
  it 'should build model' do
93
98
  u = Unit.build name: 'Zeratul'
94
99
  u.name.should == 'Zeratul'
@@ -111,7 +116,7 @@ describe "Model CRUD" do
111
116
  it 'should accept modifiers' do
112
117
  unit = Unit.create! name: 'Zeratul'
113
118
 
114
- Unit.update({_id: unit._id}, _set: {name: 'Tassadar'})
119
+ Unit.update({id: unit.id}, _set: {name: 'Tassadar'})
115
120
  unit.reload
116
121
  unit.name.should == 'Tassadar'
117
122
 
@@ -152,7 +157,7 @@ describe "Model CRUD" do
152
157
  it 'should perform CRUD' do
153
158
  # Create.
154
159
  @unit.save.should be_true
155
- @unit._id.should_not be_nil
160
+ @unit.id.should_not be_nil
156
161
 
157
162
  # Read.
158
163
  Unit.count.should == 1
@@ -85,7 +85,7 @@ describe 'Miscellaneous' do
85
85
  unit = Unit.first
86
86
  unit.name = "Tassadar"
87
87
 
88
- Unit.should_receive(:first).with(_id: unit._id).and_return{db.units.first(_id: unit._id)}
88
+ Unit.should_receive(:first).with(_id: unit.id).and_return{db.units.first(id: unit.id)}
89
89
  unit.original.name.should == "Zeratul"
90
90
  end
91
91
 
@@ -43,7 +43,7 @@ describe "Query" do
43
43
  u = Unit.build(name: 'Zeratul')
44
44
  u.save!
45
45
  Unit.first_by_name('Zeratul').name.should == 'Zeratul'
46
- Unit.by_id!(u._id).name.should == 'Zeratul'
46
+ Unit.by_id!(u.id).name.should == 'Zeratul'
47
47
  end
48
48
 
49
49
  it 'should be integrated with build, create and create!' do
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.1.1
4
+ version: 2.1.2
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-19 00:00:00.000000000Z
12
+ date: 2012-01-05 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mongodb
16
- requirement: &70215691223380 !ruby/object:Gem::Requirement
16
+ requirement: &70263477501940 !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: *70215691223380
24
+ version_requirements: *70263477501940
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: validatable2
27
- requirement: &70215691222580 !ruby/object:Gem::Requirement
27
+ requirement: &70263477501460 !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: *70215691222580
35
+ version_requirements: *70263477501460
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: ruby_ext
38
- requirement: &70215691222100 !ruby/object:Gem::Requirement
38
+ requirement: &70263477500960 !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: *70215691222100
46
+ version_requirements: *70263477500960
47
47
  description:
48
48
  email:
49
49
  executables: []