mongodb_model 0.2.8 → 2.0.0

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