mongodb_model 0.2.8 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/mongo/model.rb CHANGED
@@ -1,51 +1,6 @@
1
1
  require 'mongodb_model/gems'
2
2
 
3
- require 'validatable'
4
- require 'ruby_ext'
5
- require 'mongo/object'
6
-
7
- module Mongo::Model; end
8
-
9
- %w(
10
- support/types
11
-
12
- db
13
- conversion
14
- assignment
15
- callbacks
16
- validation
17
- validation/uniqueness_validator
18
- crud
19
- query
20
- query_mixin
21
- scope
22
- attribute_convertors
23
- misc
24
- model
25
- ).each{|f| require "mongo/model/#{f}"}
26
-
27
3
  module Mongo
28
- module Model
29
- autoload :FileModel, 'mongo/model/file_model'
30
-
31
- inherit \
32
- Db,
33
- Conversion,
34
- Assignment,
35
- Callbacks,
36
- Validation,
37
- Crud,
38
- QueryMixin,
39
- Scope,
40
- AttributeConvertors,
41
- Misc
42
- end
4
+ autoload :Model, 'mongo/model/load'
43
5
  end
44
6
 
45
- Mongo.defaults.merge! \
46
- convert_underscore_to_dollar: true,
47
- batch_size: 50,
48
- multi: true,
49
- safe: true
50
-
51
- require 'mongo/model/integration/rails' if defined? Rails
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'Model callbacks' do
3
+ describe 'Attribute assignment' do
4
4
  with_mongo_model
5
5
 
6
6
  after{remove_constants :User, :Writer}
@@ -70,7 +70,7 @@ describe 'Model callbacks' do
70
70
  [u.age, u.posts].should == [20, 12]
71
71
  end
72
72
 
73
- it 'casting smoke test' do
73
+ it 'should cast string values' do
74
74
  [
75
75
  Boolean, '1', true,
76
76
  Date, '2011-08-23', Date.parse('2011-08-23'),
@@ -5,7 +5,7 @@ describe 'Associations' do
5
5
 
6
6
  after{remove_constants :Post, :Comment}
7
7
 
8
- it "basic" do
8
+ it "should allow to model associations" do
9
9
  class Post
10
10
  inherit Mongo::Model
11
11
  collection :posts
@@ -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: [[:created_at, -1]]})
16
+ Comment.query({post_id: _id}, {sort: [[:text, -1]]})
17
17
  end
18
18
  end
19
19
 
@@ -26,8 +26,6 @@ describe 'Associations' do
26
26
  def == o
27
27
  self.class == o.class and [text, post_id] == [o.text, o.post_id]
28
28
  end
29
-
30
- timestamps!
31
29
  end
32
30
 
33
31
  post1 = Post.create! text: 'Post 1'
@@ -1,20 +1,20 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "Attribute Convertors" do
3
+ describe "Attribute convertors" do
4
4
  with_mongo_model
5
5
 
6
6
  after(:all){remove_constants :TheSample}
7
7
 
8
8
  convertors = Mongo::Model::AttributeConvertors::CONVERTORS
9
9
 
10
- it ":line convertor" do
10
+ it "should convert line of comma-separated tokens to array and backward" do
11
11
  v = ['a', 'b']
12
12
  str_v = 'a, b'
13
13
  convertors[:line][:from_string].call(str_v).should == v
14
14
  convertors[:line][:to_string].call(v).should == str_v
15
15
  end
16
16
 
17
- it ":yaml convertor" do
17
+ it "should convert to YAML and backward" do
18
18
  v = {'a' => 'b'}
19
19
  str_v = v.to_yaml.strip
20
20
 
@@ -22,14 +22,14 @@ describe "Attribute Convertors" do
22
22
  convertors[:yaml][:to_string].call(v).should == str_v
23
23
  end
24
24
 
25
- it ":json convertor" do
25
+ it "should convert to JSON and backward" do
26
26
  v = {'a' => 'b'}
27
27
  str_v = v.to_json.strip
28
28
  convertors[:json][:from_string].call(str_v).should == v
29
29
  convertors[:json][:to_string].call(v).should == str_v
30
30
  end
31
31
 
32
- it ":field should generate helper methods if :as_string option provided" do
32
+ it "should generate helper methods if :as_string option provided" do
33
33
  class ::TheSample
34
34
  inherit Mongo::Model
35
35
 
@@ -48,24 +48,24 @@ describe "Attribute Convertors" do
48
48
 
49
49
  o = TheSample.new
50
50
 
51
- # get
51
+ # Get.
52
52
  o.tags_as_string.should == ''
53
53
  o.tags = %w(Java Ruby)
54
54
  o._cache.clear
55
55
  o.tags_as_string.should == 'Java, Ruby'
56
56
 
57
- # set
57
+ # Set.
58
58
  o.tags_as_string = ''
59
59
  o.tags.should == []
60
60
  o.tags_as_string = 'Java, Ruby'
61
61
  o.tags.should == %w(Java Ruby)
62
62
 
63
- # mass assignment
63
+ # Mass assignment.
64
64
  o.tags = []
65
65
  o.set tags_as_string: 'Java, Ruby'
66
66
  o.tags.should == %w(Java Ruby)
67
67
 
68
- # # protection
68
+ # Protection.
69
69
  o.protected_tags = []
70
70
  -> {o.set protected_tags_as_string: 'Java, Ruby'}.should raise_error(/not allowed/)
71
71
  end
@@ -1,60 +1,187 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'Model callbacks' do
3
+ describe 'Callbacks' do
4
4
  with_mongo_model
5
5
 
6
- after{remove_constants :Post, :Player}
6
+ describe "basics" do
7
+ after{remove_constants :Post, :Unit}
7
8
 
8
- it "integration smoke test" do
9
- class Player
10
- inherit Mongo::Model
9
+ it "should works in common use case" do
10
+ class Unit
11
+ inherit Mongo::Model
11
12
 
12
- before_validate :before_validate_check
13
- after_save :after_save_check
13
+ before_validate :validate_unit
14
+ after_save :unit_saved
14
15
 
15
- attr_accessor :missions
16
+ attr_accessor :items
17
+ embedded :items
16
18
 
17
- class Mission
18
- inherit Mongo::Model
19
+ class Item
20
+ inherit Mongo::Model
19
21
 
20
- before_validate :before_validate_check
21
- after_save :after_save_check
22
+ before_validate :validate_item
23
+ after_save :item_saved
24
+ end
22
25
  end
23
- end
24
26
 
25
- mission = Player::Mission.new
26
- player = Player.new
27
- player.missions = [mission]
27
+ item = Unit::Item.new
28
+ unit = Unit.new
29
+ unit.items = [item]
28
30
 
29
- player.should_receive(:before_validate_check).once.ordered.and_return(nil)
30
- mission.should_receive(:before_validate_check).once.ordered.and_return(nil)
31
- player.should_receive(:after_save_check).once.ordered.and_return(nil)
32
- mission.should_receive(:after_save_check).once.ordered.and_return(nil)
31
+ unit.should_receive(:validate_unit).once.ordered.and_return(nil)
32
+ unit.should_receive(:unit_saved).once.ordered.and_return(nil)
33
+ item.should_receive(:validate_item).once.ordered.and_return(nil)
34
+ item.should_receive(:item_saved).once.ordered.and_return(nil)
33
35
 
34
- db.units.save(player).should be_true
36
+ db.units.save(unit).should be_true
37
+ end
35
38
  end
36
39
 
37
- it "should have :build callback" do
38
- class Post
39
- inherit Mongo::Model
40
- collection :posts
40
+ describe 'CRUD' do
41
+ with_mongo_model
42
+
43
+ before do
44
+ class MainObject
45
+ inherit Mongo::Model, RSpec::CallbackHelper
41
46
 
42
- class Tags < Array
47
+ attr_accessor :children
48
+ embedded :children
43
49
  end
44
50
 
45
- def tags
46
- @tags ||= Tags.new
51
+ class EmbeddedObject
52
+ inherit Mongo::Model, RSpec::CallbackHelper
47
53
  end
48
- attr_writer :tags
54
+ end
55
+ after{remove_constants :MainObject, :Post}
49
56
 
50
- after_build do |post|
51
- post.tags = Tags.new.replace post.tags
57
+ before do
58
+ @child = EmbeddedObject.new
59
+ @object = MainObject.new
60
+ @object.children = [@child]
61
+ end
62
+
63
+ it 'should fire create callbacks' do
64
+ %w(before_validate after_validate before_save before_create after_create after_save).each do |name|
65
+ @object.should_receive(name).once.ordered.and_return(true)
66
+ @child.should_receive(name).once.ordered.and_return(true)
52
67
  end
68
+
69
+ db.objects.save(@object).should be_true
53
70
  end
54
71
 
55
- post = Post.new
56
- post.save!
72
+ it 'should fire update callbacks' do
73
+ @object.dont_watch_callbacks do
74
+ db.objects.save(@object).should be_true
75
+ end
57
76
 
58
- Post.first.tags.class.should == Post::Tags
77
+ %w(before_validate after_validate before_save before_update after_update after_save).each do |name|
78
+ @object.should_receive(name).once.ordered.and_return(true)
79
+ @child.should_receive(name).once.ordered.and_return(true)
80
+ end
81
+ db.objects.save(@object).should be_true
82
+ end
83
+
84
+ it 'should fire delete callbacks' do
85
+ @object.dont_watch_callbacks do
86
+ db.objects.save(@object).should be_true
87
+ end
88
+
89
+ %w(before_validate after_validate before_delete after_delete).each do |name|
90
+ @object.should_receive(name).once.ordered.and_return(true)
91
+ @child.should_receive(name).once.ordered.and_return(true)
92
+ end
93
+ db.objects.delete(@object).should be_true
94
+ end
95
+
96
+ it 'should be able skip callbacks' do
97
+ %w(before_validate after_validate before_save before_update after_update after_save).each do |name|
98
+ @object.should_not_receive(name)
99
+ @child.should_not_receive(name)
100
+ end
101
+
102
+ db.objects.save(@object, callbacks: false).should be_true
103
+ db.objects.count.should == 1
104
+ db.objects.save(@object, callbacks: false).should be_true
105
+ db.objects.count.should == 1
106
+ db.objects.delete(@object, callbacks: false).should be_true
107
+ db.objects.count.should == 0
108
+ end
109
+
110
+ it 'should be able interrupt CRUD' do
111
+ %w(before_validate after_validate before_save).each do |name|
112
+ @object.should_receive(name).and_return true
113
+ @child.should_receive(name).and_return true
114
+ end
115
+
116
+ @object.should_receive(:before_create).and_return true
117
+ @child.should_receive(:before_create).and_return false
118
+
119
+ db.objects.save(@object).should be_false
120
+ db.objects.count.should == 0
121
+ end
122
+
123
+ # Rejected.
124
+ # describe "embedded" do
125
+ # it 'should fire :delete on detached objects' do
126
+ # db.objects.save(@object).should be_true
127
+ # @object.children.clear
128
+ # @child.should_receive(:before_delete).once.and_return(true)
129
+ # db.objects.delete(@object).should be_true
130
+ # end
131
+ #
132
+ # it 'should fire :delete on deleted objects in update' do
133
+ # db.objects.save(@object).should be_true
134
+ # @object.children.clear
135
+ # @child.should_receive(:before_delete).once.and_return(true)
136
+ # db.objects.save(@object).should be_true
137
+ # end
138
+ #
139
+ # it 'should fire :create on new objects in update' do
140
+ # db.objects.save(@object).should be_true
141
+ # child2 = EmbeddedObject.new
142
+ # @object.children << child2
143
+ # child2.should_receive(:before_create).once.and_return(true)
144
+ # child2.should_not_receive(:before_update)
145
+ # db.objects.save(@object).should be_true
146
+ # end
147
+ # end
148
+
149
+ it "should fire after build callback after building the model" do
150
+ @object.dont_watch_callbacks do
151
+ db.objects.save(@object).should be_true
152
+ end
153
+
154
+ MainObject.after_instantiate do |instance|
155
+ instance.should_receive(:after_build)
156
+ end
157
+ EmbeddedObject.after_instantiate do |instance|
158
+ instance.should_receive(:after_build)
159
+ end
160
+ db.objects.first
161
+ end
162
+
163
+ it "should allow to use after build callback to post-process and alter model" do
164
+ class Post
165
+ inherit Mongo::Model
166
+ collection :posts
167
+
168
+ class Tags < Array
169
+ end
170
+
171
+ def tags
172
+ @tags ||= Tags.new
173
+ end
174
+ attr_writer :tags
175
+
176
+ after_build do |post|
177
+ post.tags = Tags.new.replace post.tags
178
+ end
179
+ end
180
+
181
+ post = Post.new
182
+ post.save!
183
+
184
+ Post.first.tags.class.should == Post::Tags
185
+ end
59
186
  end
60
187
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'Model callbacks' do
3
+ describe 'Conversion' do
4
4
  with_mongo_model
5
5
 
6
6
  before :all do
@@ -40,7 +40,7 @@ describe 'Model callbacks' do
40
40
 
41
41
  it "should work without arguments" do
42
42
  post = build_post_with_comment
43
- post.to_rson.should == {
43
+ post.to_hash.should == {
44
44
  'text' => 'StarCraft releasing soon!',
45
45
  'token' => 'secret',
46
46
  'comments' => [
@@ -49,32 +49,32 @@ describe 'Model callbacks' do
49
49
  }
50
50
  end
51
51
 
52
- it "only, except, methods" do
52
+ it "should accept :only, :except and :methods options" do
53
53
  post = build_post_with_comment
54
- post.to_rson(only: :text).should == {'text' => 'StarCraft releasing soon!'}
55
- post.to_rson(except: :token).should == {
54
+ post.to_hash(only: :text).should == {'text' => 'StarCraft releasing soon!'}
55
+ post.to_hash(except: :token).should == {
56
56
  'text' => 'StarCraft releasing soon!',
57
57
  'comments' => [
58
58
  {'text' => 'Cool!'}
59
59
  ]
60
60
  }
61
- post.to_rson(only: [], methods: :teaser).should == {'teaser' => 'StarCraft r'}
61
+ post.to_hash(only: [], methods: :teaser).should == {'teaser' => 'StarCraft r'}
62
62
  end
63
63
 
64
- it "profiles" do
64
+ it "should use conversion profiles" do
65
65
  Post.class_eval do
66
66
  profile :public, only: [:text, :comments], methods: :teaser
67
67
  end
68
68
 
69
69
  post = build_post_with_comment
70
70
 
71
- -> {post.to_rson(profile: :public)}.should raise_error(/profile :public not defined for Comment/)
71
+ -> {post.to_hash(profile: :public)}.should raise_error(/profile :public not defined for Comment/)
72
72
 
73
73
  Comment.class_eval do
74
74
  profile :public
75
75
  end
76
76
 
77
- post.to_rson(profile: :public).should == {
77
+ post.to_hash(profile: :public).should == {
78
78
  'text' => 'StarCraft releasing soon!',
79
79
  'teaser' => 'StarCraft r',
80
80
  'comments' => [
@@ -82,7 +82,7 @@ describe 'Model callbacks' do
82
82
  ]
83
83
  }
84
84
  end
85
-
85
+
86
86
  it "should include errors" do
87
87
  Post.class_eval do
88
88
  validates_presence_of :token
@@ -90,30 +90,30 @@ describe 'Model callbacks' do
90
90
 
91
91
  post = Post.new text: 'StarCraft releasing soon!'
92
92
  post.valid?.should be_false
93
-
94
- post.to_rson.should == {
93
+
94
+ post.to_hash.should == {
95
95
  'text' => 'StarCraft releasing soon!',
96
96
  'errors' => {"token" => ["can't be empty"]}
97
97
  }
98
-
99
- post.to_rson(errors: false).should == {
98
+
99
+ post.to_hash(errors: false).should == {
100
100
  'text' => 'StarCraft releasing soon!'
101
101
  }
102
102
  end
103
103
 
104
- it "to_json" do
104
+ it "should convert to to_json" do
105
105
  post = build_post_with_comment
106
106
  rson = mock
107
107
  rson.should_receive(:to_json).and_return(:ok)
108
- post.should_receive(:to_rson).with(only: :text).and_return(rson)
108
+ post.should_receive(:to_hash).with(only: :text).and_return(rson)
109
109
  post.to_json(only: :text).should == :ok
110
110
  end
111
111
 
112
- it "to_xml" do
112
+ it "should convert to to_xml" do
113
113
  post = build_post_with_comment
114
114
  rson = mock
115
115
  rson.should_receive(:to_xml).and_return(:ok)
116
- post.should_receive(:to_rson).with(only: :text).and_return(rson)
116
+ post.should_receive(:to_hash).with(only: :text).and_return(rson)
117
117
  post.to_xml(only: :text).should == :ok
118
118
  end
119
119
  end