mongodb_model 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/lib/mongo/model.rb CHANGED
@@ -18,6 +18,7 @@ module Mongo::Model; end
18
18
  validation/uniqueness_validator
19
19
  crud
20
20
  query
21
+ query_mixin
21
22
  scope
22
23
  attribute_convertors
23
24
  file_model
@@ -33,7 +34,7 @@ module Mongo
33
34
  Callbacks,
34
35
  Validation,
35
36
  Crud,
36
- Query,
37
+ QueryMixin,
37
38
  Scope,
38
39
  AttributeConvertors,
39
40
  Mongo::Model::FileModel,
@@ -2,7 +2,7 @@ module Mongo::Model::Callbacks
2
2
  inherit RubyExt::Callbacks
3
3
 
4
4
  module ClassMethods
5
- [:validate, :update, :save, :destroy].each do |method_name|
5
+ [:validate, :create, :update, :save, :destroy].each do |method_name|
6
6
  define_method "before_#{method_name}" do |*args, &block|
7
7
  opt = args.extract_options!
8
8
  if block
@@ -1,7 +1,7 @@
1
1
  module Mongo::Model::Crud
2
- def save opts = {}
3
- with_collection opts do |collection, opts|
4
- collection.save self, opts
2
+ def save options = {}
3
+ with_collection options do |collection, options|
4
+ collection.save self, options
5
5
  end
6
6
  end
7
7
 
@@ -9,9 +9,9 @@ module Mongo::Model::Crud
9
9
  save(*args) || raise(Mongo::Error, "can't save #{self.inspect}!")
10
10
  end
11
11
 
12
- def destroy opts = {}
13
- with_collection opts do |collection, opts|
14
- collection.destroy self, opts
12
+ def destroy options = {}
13
+ with_collection options do |collection, options|
14
+ collection.destroy self, options
15
15
  end
16
16
  end
17
17
 
@@ -20,38 +20,38 @@ module Mongo::Model::Crud
20
20
  end
21
21
 
22
22
  module ClassMethods
23
- def build attributes = {}, opts = {}
24
- self.new.set attributes, opts
23
+ def build attributes = {}, options = {}
24
+ self.new.set attributes, options
25
25
  end
26
26
 
27
- def create attributes = {}, opts = {}
28
- o = build attributes, opts
27
+ def create attributes = {}, options = {}
28
+ o = build attributes, options
29
29
  o.save
30
30
  o
31
31
  end
32
32
 
33
- def create! attributes = {}, opts = {}
33
+ def create! attributes = {}, options = {}
34
34
  o = create attributes
35
35
  raise(Mongo::Error, "can't create #{attributes.inspect}!") if o.new_record?
36
36
  o
37
37
  end
38
38
 
39
- def destroy_all selector = {}, opts = {}
39
+ def destroy_all selector = {}, options = {}
40
40
  success = true
41
- collection = opts[:collection] || self.collection
41
+ collection = options[:collection] || self.collection
42
42
  each(selector){|o| success = false unless o.destroy}
43
43
  success
44
44
  end
45
45
 
46
- def destroy_all! selector = {}, opts = {}
47
- destroy_all(selector, opts) || raise(Mongo::Error, "can't destroy #{selector.inspect}!")
46
+ def destroy_all! selector = {}, options = {}
47
+ destroy_all(selector, options) || raise(Mongo::Error, "can't destroy #{selector.inspect}!")
48
48
  end
49
49
  end
50
50
 
51
51
  protected
52
- def with_collection opts, &block
53
- opts = opts.clone
54
- collection = opts.delete(:collection) || self.class.collection
55
- block.call collection, opts
52
+ def with_collection options, &block
53
+ options = options.clone
54
+ collection = options.delete(:collection) || self.class.collection
55
+ block.call collection, options
56
56
  end
57
57
  end
@@ -15,7 +15,7 @@ module Mongo::Model::FileModel
15
15
 
16
16
  before_validate do |model|
17
17
  file_model = model.send(attr_name)
18
- file_model.validate
18
+ file_model.run_validations
19
19
  model.errors[attr_name] = file_model.errors unless file_model.errors.empty?
20
20
  end
21
21
 
@@ -9,10 +9,9 @@ module Mongo::Model::Misc
9
9
  def _cache
10
10
  @_cache ||= {}
11
11
  end
12
- def _clear_cache
13
- @_cache = {}
14
- end
15
-
12
+ # def _clear_cache
13
+ # @_cache = {}
14
+ # end
16
15
 
17
16
  def dom_id
18
17
  # new_record? ? "new_#{self.class.name.underscore}" : to_param
@@ -25,6 +24,18 @@ module Mongo::Model::Misc
25
24
 
26
25
  delegate :t, to: I18n
27
26
 
27
+ def reload
28
+ obj = self.class.by_id!(_id || raise("can't reload new document (#{self})!"))
29
+ instance_variables.each{|n| remove_instance_variable n}
30
+ obj.instance_variables.each do |n|
31
+ instance_variable_set n, obj.instance_variable_get(n)
32
+ end
33
+ nil
34
+ end
35
+
36
+ def original
37
+ @_original ||= _id? ? self.class.by_id(self._id) : nil
38
+ end
28
39
 
29
40
  module ClassMethods
30
41
  delegate :t, to: I18n
@@ -1,36 +1,46 @@
1
- module Mongo::Model::Query
2
- module ClassMethods
3
- include Mongo::DynamicFinders
1
+ class Mongo::Model::Query < Object
2
+ attr_reader :model, :selector, :options
4
3
 
5
- def count selector = {}, opts = {}
6
- collection.count selector, opts
7
- end
4
+ def initialize model, selector = {}, options = {} *args
5
+ @model, @selector, @options = model, selector, options
6
+ end
8
7
 
9
- def first selector = {}, opts = {}
10
- collection.first selector, opts
11
- end
8
+ def class
9
+ ::Mongo::Model::Query
10
+ end
12
11
 
13
- def each selector = {}, opts = {}, &block
14
- collection.each selector, opts, &block
15
- end
12
+ def merge query
13
+ raise "can't merge queries with different models!" unless model == query.model
14
+ self.class.new model, selector.merge(query.selector), options.merge(query.options)
15
+ end
16
16
 
17
- def all selector = {}, opts = {}, &block
18
- if block
19
- each selector, opts, &block
20
- else
21
- list = []
22
- each(selector, opts){|doc| list << doc}
23
- list
24
- end
25
- end
17
+ def inspect
18
+ "#<Mongo::Model::Query: #{model} #{@selector.inspect} #{@options.inspect}>"
19
+ end
20
+ alias_method :to_s, :inspect
26
21
 
27
- def first! selector = {}, opts = {}
28
- first(selector, opts) || raise(Mongo::NotFound, "document with selector #{selector} not found!")
29
- end
22
+ def == o
23
+ self.class == o.class and ([model, selector, options] == [o.model, o.selector, o.options])
24
+ end
30
25
 
31
- def exists? selector = {}, opts = {}
32
- count(selector, opts) > 0
33
- end
34
- alias :exist? :exists?
26
+ def build attributes = {}, options = {}
27
+ model.build selector.merge(attributes), options
35
28
  end
29
+
30
+ def create attributes = {}, options = {}
31
+ model.create selector.merge(attributes), options
32
+ end
33
+
34
+ def create! attributes = {}, options = {}
35
+ model.create! selector.merge(attributes), options
36
+ end
37
+
38
+ protected
39
+ def method_missing method, *args, &block
40
+ model.with_scope selector, options do
41
+ result = model.send method, *args, &block
42
+ result = self.merge result if result.is_a? self.class
43
+ result
44
+ end
45
+ end
36
46
  end
@@ -0,0 +1,45 @@
1
+ module Mongo::Model::QueryMixin
2
+ module ClassMethods
3
+ include Mongo::DynamicFinders
4
+
5
+ def count selector = {}, options = {}
6
+ collection.count selector, options
7
+ end
8
+
9
+ def first selector = {}, options = {}
10
+ collection.first selector, options
11
+ end
12
+
13
+ def each selector = {}, options = {}, &block
14
+ collection.each selector, options, &block
15
+ end
16
+
17
+ def all selector = {}, options = {}, &block
18
+ if block
19
+ each selector, options, &block
20
+ else
21
+ list = []
22
+ each(selector, options){|doc| list << doc}
23
+ list
24
+ end
25
+ end
26
+
27
+ def first! selector = {}, options = {}
28
+ first(selector, options) || raise(Mongo::NotFound, "document with selector #{selector} not found!")
29
+ end
30
+
31
+ def exists? selector = {}, options = {}
32
+ count(selector, options) > 0
33
+ end
34
+ alias :exist? :exists?
35
+
36
+ def query *args
37
+ if args.first.is_a? Mongo::Model::Query
38
+ args.first
39
+ else
40
+ selector, options = args.first.is_a?(::Array) ? args.first : args
41
+ Mongo::Model::Query.new self, (selector || {}), (options || {})
42
+ end
43
+ end
44
+ end
45
+ end
@@ -1,82 +1,55 @@
1
1
  module Mongo::Model::Scope
2
- class ScopeProxy < BasicObject
3
- def initialize model, scope
4
- @model, @scope = model, scope
5
- end
6
-
7
- def class
8
- ::Mongo::Model::Scope::ScopeProxy
9
- end
10
-
11
- def reverse_merge! scope
12
- @scope = scope.merge @scope
13
- end
14
-
15
- def inspect
16
- "#<ScopeProxy:{#{scope.inspect}}>"
17
- end
18
- alias_method :to_s, :inspect
19
-
20
- protected
21
- attr_reader :model, :scope
22
-
23
- def method_missing method, *args, &block
24
- model.with_scope scope do
25
- result = model.send method, *args, &block
26
- result.reverse_merge! scope if result.class == ::Mongo::Model::Scope::ScopeProxy
27
- result
28
- end
29
- end
30
- end
31
-
32
2
  module ClassMethods
33
3
  def current_scope
34
4
  scope, exclusive = Thread.current[:mongo_model_scope]
35
- if exclusive
5
+ current = if exclusive
36
6
  scope
37
7
  elsif scope
38
- default_scope.merge scope
8
+ default_scope ? default_scope.merge(scope) : scope
39
9
  else
40
10
  default_scope
41
11
  end
42
12
  end
43
13
 
44
- def with_exclusive_scope options = {}, &block
45
- with_scope options, true, &block
14
+ def with_exclusive_scope *args, &block
15
+ with_scope *(args << true), &block
46
16
  end
47
17
 
48
- def with_scope options = {}, exclusive = false, &block
49
- previous_options, previous_exclusive = Thread.current[:mongo_model_scope]
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
23
+ end
24
+
25
+ scope = query *args
26
+ previous_scope, previous_exclusive = Thread.current[:mongo_model_scope]
50
27
  raise "exclusive scope already applied!" if previous_exclusive
51
28
 
52
29
  begin
53
- options = previous_options.merge options if previous_options and !exclusive
54
- Thread.current[:mongo_model_scope] = [options, exclusive]
30
+ scope = previous_scope.merge scope if !exclusive and previous_scope
31
+ Thread.current[:mongo_model_scope] = [scope, exclusive]
55
32
  return block.call
56
33
  ensure
57
- Thread.current[:mongo_model_scope] = [previous_options, false]
34
+ Thread.current[:mongo_model_scope] = [previous_scope, false]
58
35
  end
59
36
  end
60
37
 
61
- inheritable_accessor :_default_scope, -> {{}}
38
+ inheritable_accessor :_default_scope, nil
62
39
  def default_scope *args, &block
63
40
  if block
64
- self._default_scope = block
41
+ self._default_scope = -> {query block.call}
65
42
  elsif !args.empty?
66
- args.size.must == 1
67
- args.first.must_be.a Hash
68
- scope = args.first
69
- self._default_scope = -> {args.first}
43
+ self._default_scope = -> {query *args}
70
44
  else
71
- _default_scope.call
45
+ _default_scope && _default_scope.call
72
46
  end
73
47
  end
74
48
 
75
- def scope name, options = nil, &block
49
+ def scope name, *args, &block
76
50
  model = self
77
51
  metaclass.define_method name do
78
- scope = (block && block.call) || options
79
- ScopeProxy.new model, scope
52
+ query (block && instance_eval(&block)) || args
80
53
  end
81
54
  end
82
55
 
@@ -84,16 +57,28 @@ module Mongo::Model::Scope
84
57
  #
85
58
  # finders
86
59
  #
87
- def count selector = {}, opts = {}
88
- super current_scope.merge(selector), opts
60
+ def count selector = {}, options = {}
61
+ if current = current_scope
62
+ super current.selector.merge(selector), current.options.merge(options)
63
+ else
64
+ super selector, options
65
+ end
89
66
  end
90
67
 
91
- def first selector = {}, opts = {}
92
- super current_scope.merge(selector), opts
68
+ def first selector = {}, options = {}
69
+ if current = current_scope
70
+ super current.selector.merge(selector), current.options.merge(options)
71
+ else
72
+ super selector, options
73
+ end
93
74
  end
94
75
 
95
- def each selector = {}, opts = {}, &block
96
- super current_scope.merge(selector), opts, &block
76
+ def each selector = {}, options = {}, &block
77
+ if current = current_scope
78
+ super current.selector.merge(selector), current.options.merge(options), &block
79
+ else
80
+ super selector, options, &block
81
+ end
97
82
  end
98
83
  end
99
84
  end
@@ -1,4 +1,5 @@
1
1
  require 'mongo/object/spec'
2
+ require 'file_model/spec'
2
3
 
3
4
  rspec do
4
5
  class << self
@@ -4,7 +4,15 @@ module Mongo::Model::Validation
4
4
  end
5
5
 
6
6
  def run_validations
7
- self.class.validations.each{|v| v.validate self}
7
+ self.class.validations.each do |v|
8
+ if v.respond_to?(:validate)
9
+ v.validate self
10
+ elsif v.is_a? Proc
11
+ v.call self
12
+ else
13
+ send v
14
+ end
15
+ end
8
16
  true
9
17
  end
10
18
 
@@ -17,12 +25,16 @@ module Mongo::Model::Validation
17
25
  add_validations(args, Mongo::Model::UniquenessValidator)
18
26
  end
19
27
 
28
+ def validate validation
29
+ validations << validation
30
+ end
31
+
20
32
  protected
21
33
  def add_validations(args, klass)
22
34
  options = args.last.is_a?(Hash) ? args.pop : {}
23
35
  args.each do |attribute|
24
36
  new_validation = klass.new self, attribute, options
25
- validations << new_validation
37
+ validate new_validation
26
38
  end
27
39
  end
28
40
  end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe 'Model callbacks' do
4
- with_mongo
4
+ with_mongo_model
5
5
 
6
6
  after{remove_constants :User, :Writer}
7
7
 
@@ -26,6 +26,9 @@ describe 'Model callbacks' do
26
26
  assign do
27
27
  name String, true
28
28
  has_mail Boolean, true
29
+ end
30
+
31
+ assign do
29
32
  age Integer, true
30
33
  position true
31
34
  banned Boolean
@@ -40,7 +43,7 @@ describe 'Model callbacks' do
40
43
  u.set! banned: '0'
41
44
  u.banned.should == false
42
45
  end
43
-
46
+
44
47
  it "should inherit assignment rules" do
45
48
  class User
46
49
  inherit Mongo::Model
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Associations' do
4
+ with_mongo_model
5
+
6
+ after{remove_constants :Post, :Comment}
7
+
8
+ it "basic" do
9
+ class Post
10
+ inherit Mongo::Model
11
+ collection :posts
12
+
13
+ attr_accessor :text
14
+
15
+ def comments
16
+ Comment.query({post_id: _id}, {sort: [[:created_at, -1]]})
17
+ end
18
+ end
19
+
20
+ class Comment
21
+ inherit Mongo::Model
22
+ collection :comments
23
+
24
+ attr_accessor :text, :post_id
25
+
26
+ def == o
27
+ [self.class, text, post_id] == [o.class, o.text, o.post_id]
28
+ end
29
+
30
+ timestamps!
31
+ end
32
+
33
+ post1 = Post.create! text: 'Post 1'
34
+ comment1 = post1.comments.create! text: 'Comment 1'
35
+ comment2 = post1.comments.create! text: 'Comment 2'
36
+
37
+ post2 = Post.create! text: 'Post 2'
38
+ comment3 = post2.comments.create! text: 'Comment 3'
39
+
40
+ post1.comments.count.should == 2
41
+ post1.comments.all.should == [comment2, comment1]
42
+ end
43
+ end
@@ -51,7 +51,7 @@ describe "Attribute Convertors" do
51
51
  # get
52
52
  o.tags_as_string.should == ''
53
53
  o.tags = %w(Java Ruby)
54
- o._clear_cache
54
+ o._cache.clear
55
55
  o.tags_as_string.should == 'Java, Ruby'
56
56
 
57
57
  # set
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe 'Model callbacks' do
4
- with_mongo
4
+ with_mongo_model
5
5
 
6
6
  after(:all){remove_constants :TheModel, :Player}
7
7
 
data/spec/db_spec.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe 'Collection & Database' do
4
- with_mongo
4
+ with_mongo_model
5
5
 
6
6
  before :all do
7
7
  class TheModel
@@ -12,6 +12,8 @@ describe 'File Model' do
12
12
  inherit Mongo::Model
13
13
  collection :units
14
14
 
15
+ attr_accessor :name
16
+
15
17
  mount_file :image, ImageFile
16
18
  end
17
19
  end
data/spec/misc_spec.rb CHANGED
@@ -7,6 +7,8 @@ describe 'Model Miscellaneous' do
7
7
  class User
8
8
  inherit Mongo::Model
9
9
  collection :users
10
+
11
+ attr_accessor :name
10
12
  end
11
13
  end
12
14
  after{remove_constants :Unit3, :User}
@@ -55,4 +57,11 @@ describe 'Model Miscellaneous' do
55
57
  u.save!
56
58
  u.dom_id.should_not be_empty
57
59
  end
60
+
61
+ it 'reload' do
62
+ u = User.create! name: 'Zeratul'
63
+ u.name = 'Jim'
64
+ u.reload
65
+ u.name.should == 'Zeratul'
66
+ end
58
67
  end
data/spec/query_spec.rb CHANGED
@@ -11,7 +11,7 @@ describe "Model Query" do
11
11
  attr_accessor :name
12
12
  end
13
13
  end
14
- after(:all){remove_constants :Unit}
14
+ after(:all){remove_constants :Unit, :SpecialUnit}
15
15
 
16
16
  before{@zeratul = Unit.build name: 'Zeratul'}
17
17
 
@@ -40,7 +40,28 @@ describe "Model Query" do
40
40
 
41
41
  it 'dynamic finders integration' do
42
42
  Unit.first_by_name('Zeratul').should be_nil
43
- Unit.build(name: 'Zeratul').save!
43
+ u = Unit.build(name: 'Zeratul')
44
+ u.save!
44
45
  Unit.first_by_name('Zeratul').name.should == 'Zeratul'
46
+ Unit.by_id!(u._id).name.should == 'Zeratul'
47
+ end
48
+
49
+ it 'build, create, create!' do
50
+ class SpecialUnit < Unit
51
+ attr_accessor :age
52
+ end
53
+
54
+ u = SpecialUnit.query(name: 'Zeratul').build age: 500
55
+ [u.name, u.age].should == ['Zeratul', 500]
56
+
57
+ SpecialUnit.destroy_all
58
+ SpecialUnit.query(name: 'Zeratul').create age: 500
59
+ u = SpecialUnit.first
60
+ [u.name, u.age].should == ['Zeratul', 500]
61
+
62
+ SpecialUnit.destroy_all
63
+ SpecialUnit.query(name: 'Zeratul').create! age: 500
64
+ u = SpecialUnit.first
65
+ [u.name, u.age].should == ['Zeratul', 500]
45
66
  end
46
67
  end
data/spec/scope_spec.rb CHANGED
@@ -25,7 +25,7 @@ describe "Scope" do
25
25
  Unit.first(name: 'Tassadar').should_not be_nil
26
26
  Unit.first!(name: 'Tassadar').should_not be_nil
27
27
 
28
- Unit.stub!(:current_scope).and_return(status: 'alive')
28
+ Unit.stub!(:current_scope).and_return(Unit.query(status: 'alive'))
29
29
 
30
30
  Unit.count.should == 2
31
31
  Unit.all.size.should == 2
@@ -42,61 +42,62 @@ describe "Scope" do
42
42
 
43
43
  describe 'default scope' do
44
44
  it "should not affect objects without default_scope" do
45
- Unit.current_scope.should == {}
45
+ Unit.current_scope.should be_nil
46
46
  end
47
47
 
48
48
  it "definition" do
49
49
  Unit.default_scope status: 'alive'
50
- Unit.current_scope.should == {status: 'alive'}
50
+
51
+ Unit.current_scope.should == Unit.query(status: 'alive')
51
52
 
52
53
  Unit.default_scope do
53
54
  {status: 'alive'}
54
55
  end
55
- Unit.current_scope.should == {status: 'alive'}
56
+ Unit.current_scope.should == Unit.query(status: 'alive')
56
57
  end
57
58
 
58
59
  it "should be inherited" do
59
60
  Unit.default_scope status: 'alive'
60
61
 
61
62
  class Protoss < Unit; end
62
- Protoss.current_scope.should == {status: 'alive'}
63
+ Protoss.current_scope.should == Unit.query(status: 'alive')
63
64
 
64
65
  Protoss.default_scope status: 'dead'
65
- Unit.current_scope.should == {status: 'alive'}
66
- Protoss.current_scope.should == {status: 'dead'}
66
+ Unit.current_scope.should == Unit.query(status: 'alive')
67
+ Protoss.current_scope.should == Protoss.query(status: 'dead')
67
68
  end
68
69
  end
69
70
 
70
71
  describe 'scope' do
71
72
  it "definition" do
72
73
  Unit.scope :alive, status: 'alive'
73
- Unit.alive.current_scope.should == {status: 'alive'}
74
+ Unit.alive.current_scope.should == Unit.query(status: 'alive')
74
75
 
75
76
  Unit.scope :alive do
76
77
  {status: 'alive'}
77
78
  end
78
- Unit.alive.current_scope.should == {status: 'alive'}
79
+ Unit.alive.current_scope.should == Unit.query(status: 'alive')
79
80
  end
80
81
 
81
82
  it 'scope should affect current scope' do
82
83
  Unit.scope :alive, status: 'alive'
83
84
 
84
- Unit.current_scope.should == {}
85
+ Unit.current_scope.should be_nil
85
86
 
86
- Unit.alive.current_scope.should == {status: 'alive'}
87
- Unit.alive.should == Unit
87
+ Unit.alive.current_scope.should == Unit.query(status: 'alive')
88
+ Unit.alive.class.should == Mongo::Model::Query
88
89
  end
89
90
 
90
91
  it 'should be merged with default scope' do
91
92
  Unit.default_scope race: 'Protoss'
92
93
  Unit.scope :alive, status: 'alive'
93
- Unit.alive.current_scope.should == {race: 'Protoss', status: 'alive'}
94
+ Unit.alive.current_scope.should == Unit.query(race: 'Protoss', status: 'alive')
94
95
  end
95
96
 
96
97
  it 'should allow to chain scopes' do
97
98
  Unit.scope :alive, status: 'alive'
98
99
  Unit.scope :protosses, race: 'Protoss'
99
- Unit.alive.protosses.current_scope.should == {race: 'Protoss', status: 'alive'}
100
+ Unit.alive.protosses.current_scope.should == Unit.query(race: 'Protoss', status: 'alive')
100
101
  end
101
102
  end
102
103
 
@@ -119,21 +120,21 @@ describe "Scope" do
119
120
  Unit.default_scope status: 'alive'
120
121
 
121
122
  Unit.with_scope race: 'Protoss' do
122
- Unit.current_scope.should == {status: 'alive', race: 'Protoss'}
123
+ Unit.current_scope.should == Unit.query(status: 'alive', race: 'Protoss')
123
124
 
124
125
  Unit.with_exclusive_scope do
125
- Unit.current_scope.should == {}
126
+ Unit.current_scope.should == Unit.query({})
126
127
  end
127
128
 
128
129
  Unit.with_exclusive_scope race: 'Terran' do
129
- Unit.current_scope.should == {race: 'Terran'}
130
+ Unit.current_scope.should == Unit.query(race: 'Terran')
130
131
  end
131
132
  end
132
133
  end
133
134
 
134
135
  it "usage" do
135
136
  Unit.with_scope status: 'alive' do
136
- Unit.current_scope.should == {status: 'alive'}
137
+ Unit.current_scope.should == Unit.query(status: 'alive')
137
138
  end
138
139
  end
139
140
 
@@ -141,7 +142,7 @@ describe "Scope" do
141
142
  Unit.default_scope status: 'alive'
142
143
  Unit.with_scope race: 'Protoss' do
143
144
  Unit.with_scope name: 'Zeratul' do
144
- Unit.current_scope.should == {name: 'Zeratul', race: 'Protoss', status: 'alive'}
145
+ Unit.current_scope.should == Unit.query(name: 'Zeratul', race: 'Protoss', status: 'alive')
145
146
  end
146
147
  end
147
148
  end
@@ -19,7 +19,7 @@ describe "Validations" do
19
19
  class Unit < BaseUnit
20
20
  before_validate :check_name
21
21
  def check_name
22
- errors[:name] = 'invalid name'
22
+ errors.add :name, 'invalid name'
23
23
  end
24
24
  end
25
25
 
@@ -41,6 +41,19 @@ describe "Validations" do
41
41
  unit.save.should be_true
42
42
  end
43
43
 
44
+ it "should add custom validations" do
45
+ class Unit < BaseUnit
46
+ validate :check_name
47
+ def check_name
48
+ errors.add :name, 'invalid name'
49
+ end
50
+ end
51
+
52
+ unit = Unit.new
53
+ unit.save.should be_false
54
+ unit.errors[:name].should == ['invalid name']
55
+ end
56
+
44
57
  # it "should check :errors only and ignore valid? method" do
45
58
  # unit = BaseUnit.build name: 'Zeratul'
46
59
  # unit.should_not_receive(:valid?)
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
4
+ version: 0.0.5
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-08-30 00:00:00.000000000Z
12
+ date: 2011-09-01 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: i18n
16
- requirement: &2781840 !ruby/object:Gem::Requirement
16
+ requirement: &2780720 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0.5'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2781840
24
+ version_requirements: *2780720
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: mongodb
27
- requirement: &2781540 !ruby/object:Gem::Requirement
27
+ requirement: &2780430 !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: *2781540
35
+ version_requirements: *2780430
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: file_model
38
- requirement: &2781240 !ruby/object:Gem::Requirement
38
+ requirement: &2780140 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *2781240
46
+ version_requirements: *2780140
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: validatable2
49
- requirement: &2780950 !ruby/object:Gem::Requirement
49
+ requirement: &2779840 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *2780950
57
+ version_requirements: *2779840
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: ruby_ext
60
- requirement: &2780660 !ruby/object:Gem::Requirement
60
+ requirement: &2779540 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,7 +65,7 @@ dependencies:
65
65
  version: '0'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *2780660
68
+ version_requirements: *2779540
69
69
  description:
70
70
  email:
71
71
  executables: []
@@ -83,6 +83,7 @@ files:
83
83
  - lib/mongo/model/misc.rb
84
84
  - lib/mongo/model/model.rb
85
85
  - lib/mongo/model/query.rb
86
+ - lib/mongo/model/query_mixin.rb
86
87
  - lib/mongo/model/scope.rb
87
88
  - lib/mongo/model/spec.rb
88
89
  - lib/mongo/model/support/types.rb
@@ -91,6 +92,7 @@ files:
91
92
  - lib/mongo/model.rb
92
93
  - lib/mongodb_model/gems.rb
93
94
  - spec/assignment_spec.rb
95
+ - spec/associations_spec.rb
94
96
  - spec/attribute_convertors_spec.rb
95
97
  - spec/callbacks_spec.rb
96
98
  - spec/crud_spec.rb