mongodb_model 2.1.1 → 2.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []