schema_validations 2.2.0 → 2.4.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.
- checksums.yaml +5 -5
- data/.github/workflows/prs.yml +134 -0
- data/.gitignore +1 -0
- data/.simplecov +20 -0
- data/.travis.yml +6 -3
- data/Gemfile +5 -0
- data/README.md +25 -6
- data/Rakefile +2 -0
- data/gemfiles/Gemfile.base +1 -1
- data/gemfiles/activerecord-5.2/Gemfile.base +4 -0
- data/gemfiles/activerecord-5.2/Gemfile.mysql2 +10 -0
- data/gemfiles/activerecord-5.2/Gemfile.postgresql +10 -0
- data/gemfiles/{activerecord-5.0 → activerecord-5.2}/Gemfile.sqlite3 +3 -3
- data/gemfiles/activerecord-6.0/Gemfile.base +4 -0
- data/gemfiles/activerecord-6.0/Gemfile.mysql2 +10 -0
- data/gemfiles/activerecord-6.0/Gemfile.postgresql +10 -0
- data/gemfiles/{activerecord-4.2 → activerecord-6.0}/Gemfile.sqlite3 +3 -3
- data/init.rb +2 -0
- data/lib/schema_validations/active_record/type.rb +2 -0
- data/lib/schema_validations/active_record/validations.rb +8 -1
- data/lib/schema_validations/railtie.rb +2 -0
- data/lib/schema_validations/validators/not_nil_validator.rb +13 -0
- data/lib/schema_validations/version.rb +3 -1
- data/lib/schema_validations.rb +3 -0
- data/schema_dev.yml +5 -3
- data/schema_validations.gemspec +23 -27
- data/spec/spec_helper.rb +22 -18
- data/spec/support/active_model.rb +2 -0
- data/spec/validations_spec.rb +138 -73
- metadata +38 -94
- data/gemfiles/activerecord-4.2/Gemfile.base +0 -3
- data/gemfiles/activerecord-4.2/Gemfile.mysql2 +0 -10
- data/gemfiles/activerecord-4.2/Gemfile.postgresql +0 -10
- data/gemfiles/activerecord-5.0/Gemfile.base +0 -3
- data/gemfiles/activerecord-5.0/Gemfile.mysql2 +0 -10
- data/gemfiles/activerecord-5.0/Gemfile.postgresql +0 -10
- data/spec/schema_validations.sqlite3 +0 -0
data/spec/validations_spec.rb
CHANGED
|
@@ -1,38 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
4
|
|
|
3
5
|
describe "Validations" do
|
|
4
6
|
|
|
5
7
|
before(:each) do
|
|
6
|
-
|
|
8
|
+
define_schema do
|
|
7
9
|
|
|
8
|
-
create_table :articles, :
|
|
9
|
-
t.string :title, :
|
|
10
|
-
t.text :content, :
|
|
10
|
+
create_table :articles, force: true do |t|
|
|
11
|
+
t.string :title, limit: 50
|
|
12
|
+
t.text :content, null: false
|
|
11
13
|
t.integer :state
|
|
12
14
|
t.integer :votes
|
|
13
|
-
t.float :average_mark, :
|
|
14
|
-
t.boolean :active, :
|
|
15
|
-
t.decimal :max10, :
|
|
16
|
-
t.decimal :arbitrary, :
|
|
17
|
-
t.decimal :max100, :
|
|
15
|
+
t.float :average_mark, null: false
|
|
16
|
+
t.boolean :active, null: false
|
|
17
|
+
t.decimal :max10, precision: 2, scale: 1
|
|
18
|
+
t.decimal :arbitrary, precision: nil, scale: nil
|
|
19
|
+
t.decimal :max100, precision: 2, scale: nil
|
|
18
20
|
end
|
|
19
|
-
add_index :articles, :title, :
|
|
20
|
-
add_index :articles, [:state, :active], :
|
|
21
|
+
add_index :articles, :title, unique: true
|
|
22
|
+
add_index :articles, [:state, :active], unique: true
|
|
21
23
|
|
|
22
|
-
create_table :reviews, :
|
|
23
|
-
t.integer :article_id, :
|
|
24
|
-
t.string :author, :
|
|
25
|
-
t.string :content, :
|
|
24
|
+
create_table :reviews, force: true do |t|
|
|
25
|
+
t.integer :article_id, null: false
|
|
26
|
+
t.string :author, null: false
|
|
27
|
+
t.string :content, limit: 200
|
|
26
28
|
t.string :type
|
|
27
|
-
t.timestamps :
|
|
29
|
+
t.timestamps null: false
|
|
28
30
|
end
|
|
29
|
-
add_index :reviews, :article_id, :
|
|
31
|
+
add_index :reviews, :article_id, unique: true
|
|
30
32
|
|
|
31
|
-
create_table :article_reviews, :
|
|
33
|
+
create_table :article_reviews, force: true do |t|
|
|
32
34
|
t.integer :article_id
|
|
33
35
|
t.integer :review_id
|
|
34
36
|
end
|
|
35
|
-
add_index :article_reviews, [:article_id, :review_id], :
|
|
37
|
+
add_index :article_reviews, [:article_id, :review_id], unique: true
|
|
36
38
|
end
|
|
37
39
|
end
|
|
38
40
|
|
|
@@ -43,8 +45,8 @@ describe "Validations" do
|
|
|
43
45
|
|
|
44
46
|
class Review < ActiveRecord::Base
|
|
45
47
|
belongs_to :article
|
|
46
|
-
belongs_to :news_article, :
|
|
47
|
-
schema_validations :
|
|
48
|
+
belongs_to :news_article, class_name: 'Article', foreign_key: :article_id
|
|
49
|
+
schema_validations except: :content
|
|
48
50
|
end
|
|
49
51
|
|
|
50
52
|
class ArticleReview < ActiveRecord::Base
|
|
@@ -81,15 +83,15 @@ describe "Validations" do
|
|
|
81
83
|
end
|
|
82
84
|
|
|
83
85
|
it "should check title length" do
|
|
84
|
-
expect(Article.new(:
|
|
86
|
+
expect(Article.new(title: 'a' * 100).error_on(:title).size).to eq(1)
|
|
85
87
|
end
|
|
86
88
|
|
|
87
89
|
it "should validate state numericality" do
|
|
88
|
-
expect(Article.new(:
|
|
90
|
+
expect(Article.new(state: 'unknown').error_on(:state).size).to eq(1)
|
|
89
91
|
end
|
|
90
92
|
|
|
91
93
|
it "should validate if state is integer" do
|
|
92
|
-
expect(Article.new(:
|
|
94
|
+
expect(Article.new(state: 1.23).error_on(:state).size).to eq(1)
|
|
93
95
|
end
|
|
94
96
|
|
|
95
97
|
it "should validate the range of votes" do
|
|
@@ -115,28 +117,28 @@ describe "Validations" do
|
|
|
115
117
|
expect(Article.new(max100: -100).error_on(:max100).size).to eq(1)
|
|
116
118
|
end
|
|
117
119
|
|
|
118
|
-
it "should not validate the range of arbitrary decimal", :
|
|
120
|
+
it "should not validate the range of arbitrary decimal", mysql: :skip do # mysql provides a default precision
|
|
119
121
|
expect(Article.new(arbitrary: Float::MAX).error_on(:arbitrary).size).to eq(0)
|
|
120
122
|
end
|
|
121
123
|
|
|
122
124
|
it "should validate average_mark numericality" do
|
|
123
|
-
expect(Article.new(:
|
|
125
|
+
expect(Article.new(average_mark: "high").error_on(:average_mark).size).to eq(1)
|
|
124
126
|
end
|
|
125
127
|
|
|
126
128
|
it "should validate boolean fields" do
|
|
127
|
-
expect(Article.new(:
|
|
129
|
+
expect(Article.new(active: nil).error_on(:active).size).to eq(1)
|
|
128
130
|
end
|
|
129
131
|
|
|
130
132
|
it "should validate title uniqueness" do
|
|
131
133
|
article1 = Article.create(valid_article_attributes)
|
|
132
|
-
article2 = Article.new(:
|
|
134
|
+
article2 = Article.new(title: valid_article_attributes[:title])
|
|
133
135
|
expect(article2.error_on(:title).size).to eq(1)
|
|
134
136
|
article1.destroy
|
|
135
137
|
end
|
|
136
138
|
|
|
137
139
|
it "should validate state uniqueness in scope of 'active' value" do
|
|
138
140
|
article1 = Article.create(valid_article_attributes)
|
|
139
|
-
article2 = Article.new(valid_article_attributes.merge(:
|
|
141
|
+
article2 = Article.new(valid_article_attributes.merge(title: 'SchemaPlus 2.0 released'))
|
|
140
142
|
expect(article2).not_to be_valid
|
|
141
143
|
article2.toggle(:active)
|
|
142
144
|
expect(article2).to be_valid
|
|
@@ -151,9 +153,9 @@ describe "Validations" do
|
|
|
151
153
|
it "should validate uniqueness of belongs_to association" do
|
|
152
154
|
article = Article.create(valid_article_attributes)
|
|
153
155
|
expect(article).to be_valid
|
|
154
|
-
review1 = Review.create(:
|
|
156
|
+
review1 = Review.create(article: article, author: 'michal')
|
|
155
157
|
expect(review1).to be_valid
|
|
156
|
-
review2 = Review.new(:
|
|
158
|
+
review2 = Review.new(article: article, author: 'michal')
|
|
157
159
|
expect(review2.error_on(:article_id).size).to be >= 1
|
|
158
160
|
end
|
|
159
161
|
|
|
@@ -162,18 +164,81 @@ describe "Validations" do
|
|
|
162
164
|
end
|
|
163
165
|
|
|
164
166
|
it "should not validate uniqueness when scope is absent" do
|
|
165
|
-
article_review_1 = ArticleReview.create(:
|
|
167
|
+
article_review_1 = ArticleReview.create(article_id: 1, review_id: nil)
|
|
166
168
|
expect(article_review_1).to be_valid
|
|
167
169
|
|
|
168
|
-
article_review_2 = ArticleReview.create(:
|
|
170
|
+
article_review_2 = ArticleReview.create(article_id: 1, review_id: nil)
|
|
169
171
|
expect(article_review_2).to be_valid
|
|
170
172
|
|
|
171
|
-
article_review_3 = ArticleReview.create(:
|
|
173
|
+
article_review_3 = ArticleReview.create(article_id: nil, review_id: 1)
|
|
172
174
|
expect(article_review_3).to be_valid
|
|
173
175
|
|
|
174
|
-
article_review_4 = ArticleReview.create(:
|
|
176
|
+
article_review_4 = ArticleReview.create(article_id: nil, review_id: 1)
|
|
175
177
|
expect(article_review_4).to be_valid
|
|
176
178
|
end
|
|
179
|
+
|
|
180
|
+
context 'when NOT NULL validations' do
|
|
181
|
+
before(:each) do
|
|
182
|
+
ActiveRecord::Schema.define do
|
|
183
|
+
create_table :anti_nulls, force: true do |t|
|
|
184
|
+
t.string :no_default, null: false
|
|
185
|
+
t.string :blank_default, default: '', null: false
|
|
186
|
+
t.string :non_blank_default, default: 'not blank', null: false
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
with_auto_validations do
|
|
190
|
+
class AntiNull < ActiveRecord::Base
|
|
191
|
+
def self.all_blank
|
|
192
|
+
@all_blank ||= AntiNull.new(
|
|
193
|
+
no_default: '',
|
|
194
|
+
blank_default: '',
|
|
195
|
+
non_blank_default: ''
|
|
196
|
+
)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def self.all_non_blank
|
|
200
|
+
@all_non_blank ||= AntiNull.new(
|
|
201
|
+
no_default: 'foo',
|
|
202
|
+
blank_default: 'bar',
|
|
203
|
+
non_blank_default: 'baz'
|
|
204
|
+
)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def self.all_nil
|
|
208
|
+
@all_nil ||= AntiNull.new(
|
|
209
|
+
no_default: nil,
|
|
210
|
+
blank_default: nil,
|
|
211
|
+
non_blank_default: nil
|
|
212
|
+
)
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def self.non_null_with(**fields)
|
|
216
|
+
opts = { no_default: 'foo' }.merge!(fields)
|
|
217
|
+
AntiNull.new **opts
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
it 'should fail validation on empty fields only if the default value is not blank' do
|
|
226
|
+
expect(AntiNull.all_nil.error_on(:no_default).size).to eq(1)
|
|
227
|
+
expect(AntiNull.all_nil.error_on(:blank_default).size).to eq(1)
|
|
228
|
+
expect(AntiNull.all_nil.error_on(:non_blank_default).size).to eq(1)
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
it 'should fail validation on empty fields only if the default value is not blank' do
|
|
232
|
+
expect(AntiNull.all_blank.error_on(:no_default).size).to eq(1)
|
|
233
|
+
expect(AntiNull.all_blank.error_on(:non_blank_default).size).to eq(1)
|
|
234
|
+
expect(AntiNull.all_blank.error_on(:blank_default)).to be_empty
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
it 'should not fail if fields are neither nil nor empty' do
|
|
238
|
+
expect(AntiNull.all_non_blank).to be_valid
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
end
|
|
177
242
|
end
|
|
178
243
|
|
|
179
244
|
context "auto-created but changed" do
|
|
@@ -182,62 +247,62 @@ describe "Validations" do
|
|
|
182
247
|
class Article < ActiveRecord::Base ; end
|
|
183
248
|
class Review < ActiveRecord::Base
|
|
184
249
|
belongs_to :article
|
|
185
|
-
belongs_to :news_article, :
|
|
250
|
+
belongs_to :news_article, class_name: 'Article', foreign_key: :article_id
|
|
186
251
|
end
|
|
187
252
|
end
|
|
188
253
|
@too_big_content = 'a' * 1000
|
|
189
254
|
end
|
|
190
255
|
|
|
191
256
|
it "would normally have an error" do
|
|
192
|
-
@review = Review.new(:
|
|
257
|
+
@review = Review.new(content: @too_big_content)
|
|
193
258
|
expect(@review.error_on(:content).size).to eq(1)
|
|
194
259
|
expect(@review.error_on(:author).size).to eq(1)
|
|
195
260
|
end
|
|
196
261
|
|
|
197
262
|
it "shouldn't validate fields passed to :except option" do
|
|
198
|
-
Review.schema_validations :
|
|
199
|
-
@review = Review.new(:
|
|
263
|
+
Review.schema_validations except: :content
|
|
264
|
+
@review = Review.new(content: @too_big_content)
|
|
200
265
|
expect(@review.errors_on(:content).size).to eq(0)
|
|
201
266
|
expect(@review.error_on(:author).size).to eq(1)
|
|
202
267
|
end
|
|
203
268
|
|
|
204
269
|
it "shouldn't validate the fields in default whitelist" do
|
|
205
|
-
Review.schema_validations :
|
|
270
|
+
Review.schema_validations except: :content
|
|
206
271
|
expect(Review.new.error_on(:updated_at).size).to eq(0)
|
|
207
272
|
expect(Review.new.error_on(:created_at).size).to eq(0)
|
|
208
273
|
end
|
|
209
274
|
|
|
210
275
|
it "shouldn't validate the fields in whitelist" do
|
|
211
|
-
Review.schema_validations :
|
|
276
|
+
Review.schema_validations except: :content, whitelist: [:updated_at]
|
|
212
277
|
expect(Review.new.error_on(:updated_at).size).to eq(0)
|
|
213
278
|
expect(Review.new.error_on(:created_at).size).to eq(1)
|
|
214
279
|
end
|
|
215
280
|
|
|
216
281
|
it "shouldn't validate types passed to :except_type option using full validation" do
|
|
217
|
-
Review.schema_validations :
|
|
218
|
-
@review = Review.new(:
|
|
282
|
+
Review.schema_validations except_type: :validates_length_of
|
|
283
|
+
@review = Review.new(content: @too_big_content)
|
|
219
284
|
expect(@review.errors_on(:content).size).to eq(0)
|
|
220
285
|
expect(@review.error_on(:author).size).to eq(1)
|
|
221
286
|
end
|
|
222
287
|
|
|
223
288
|
it "shouldn't validate types passed to :except_type option using shorthand" do
|
|
224
|
-
Review.schema_validations :
|
|
225
|
-
@review = Review.new(:
|
|
289
|
+
Review.schema_validations except_type: :length
|
|
290
|
+
@review = Review.new(content: @too_big_content)
|
|
226
291
|
expect(@review.errors_on(:content).size).to eq(0)
|
|
227
292
|
expect(@review.error_on(:author).size).to eq(1)
|
|
228
293
|
end
|
|
229
294
|
|
|
230
295
|
it "should only validate type passed to :only_type option" do
|
|
231
|
-
Review.schema_validations :
|
|
232
|
-
@review = Review.new(:
|
|
296
|
+
Review.schema_validations only_type: :length
|
|
297
|
+
@review = Review.new(content: @too_big_content)
|
|
233
298
|
expect(@review.error_on(:content).size).to eq(1)
|
|
234
299
|
expect(@review.errors_on(:author).size).to eq(0)
|
|
235
300
|
end
|
|
236
301
|
|
|
237
302
|
|
|
238
303
|
it "shouldn't create validations if locally disabled" do
|
|
239
|
-
Review.schema_validations :
|
|
240
|
-
@review = Review.new(:
|
|
304
|
+
Review.schema_validations auto_create: false
|
|
305
|
+
@review = Review.new(content: @too_big_content)
|
|
241
306
|
expect(@review.errors_on(:content).size).to eq(0)
|
|
242
307
|
expect(@review.error_on(:author).size).to eq(0)
|
|
243
308
|
end
|
|
@@ -251,23 +316,23 @@ describe "Validations" do
|
|
|
251
316
|
before(:each) do
|
|
252
317
|
class Review < ActiveRecord::Base
|
|
253
318
|
belongs_to :article
|
|
254
|
-
belongs_to :news_article, :
|
|
319
|
+
belongs_to :news_article, class_name: 'Article', foreign_key: :article_id
|
|
255
320
|
end
|
|
256
321
|
@too_big_content = 'a' * 1000
|
|
257
322
|
end
|
|
258
323
|
|
|
259
324
|
it "should not create validation" do
|
|
260
|
-
expect(Review.new(:
|
|
325
|
+
expect(Review.new(content: @too_big_title).errors_on(:content).size).to eq(0)
|
|
261
326
|
end
|
|
262
327
|
|
|
263
328
|
it "should create validation if locally enabled explicitly" do
|
|
264
|
-
Review.schema_validations :
|
|
265
|
-
expect(Review.new(:
|
|
329
|
+
Review.schema_validations auto_create: true
|
|
330
|
+
expect(Review.new(content: @too_big_content).error_on(:content).size).to eq(1)
|
|
266
331
|
end
|
|
267
332
|
|
|
268
333
|
it "should create validation if locally enabled implicitly" do
|
|
269
334
|
Review.schema_validations
|
|
270
|
-
expect(Review.new(:
|
|
335
|
+
expect(Review.new(content: @too_big_content).error_on(:content).size).to eq(1)
|
|
271
336
|
end
|
|
272
337
|
|
|
273
338
|
end
|
|
@@ -275,18 +340,18 @@ describe "Validations" do
|
|
|
275
340
|
context "manually invoked" do
|
|
276
341
|
before(:each) do
|
|
277
342
|
class Article < ActiveRecord::Base ; end
|
|
278
|
-
Article.schema_validations :
|
|
343
|
+
Article.schema_validations only: [:title, :state]
|
|
279
344
|
|
|
280
345
|
class Review < ActiveRecord::Base
|
|
281
346
|
belongs_to :dummy_association
|
|
282
|
-
schema_validations :
|
|
347
|
+
schema_validations except: :content
|
|
283
348
|
end
|
|
284
349
|
end
|
|
285
350
|
|
|
286
351
|
it "should validate fields passed to :only option" do
|
|
287
352
|
too_big_title = 'a' * 100
|
|
288
353
|
wrong_state = 'unknown'
|
|
289
|
-
article = Article.new(:
|
|
354
|
+
article = Article.new(title: too_big_title, state: wrong_state)
|
|
290
355
|
expect(article.error_on(:title).size).to eq(1)
|
|
291
356
|
expect(article.error_on(:state).size).to eq(1)
|
|
292
357
|
end
|
|
@@ -317,7 +382,7 @@ describe "Validations" do
|
|
|
317
382
|
belongs_to :article
|
|
318
383
|
end
|
|
319
384
|
@columns = Review.content_columns.dup
|
|
320
|
-
Review.schema_validations :
|
|
385
|
+
Review.schema_validations only: [:title]
|
|
321
386
|
end
|
|
322
387
|
|
|
323
388
|
it "shouldn't validate associations not included in :only option" do
|
|
@@ -352,9 +417,9 @@ describe "Validations" do
|
|
|
352
417
|
context "when used with enum" do
|
|
353
418
|
it "does not validate numericality" do
|
|
354
419
|
class Article < ActiveRecord::Base
|
|
355
|
-
enum :
|
|
420
|
+
enum state: [:happy, :sad]
|
|
356
421
|
end
|
|
357
|
-
expect(Article.new(valid_article_attributes.merge(:
|
|
422
|
+
expect(Article.new(valid_article_attributes.merge(state: :happy))).to be_valid
|
|
358
423
|
end
|
|
359
424
|
end if ActiveRecord::Base.respond_to? :enum
|
|
360
425
|
|
|
@@ -366,11 +431,11 @@ describe "Validations" do
|
|
|
366
431
|
context 'without scope' do
|
|
367
432
|
before do
|
|
368
433
|
ActiveRecord::Schema.define do
|
|
369
|
-
create_table :books, :
|
|
434
|
+
create_table :books, force: true do |t|
|
|
370
435
|
t.string :title
|
|
371
436
|
end
|
|
372
437
|
|
|
373
|
-
add_index :books, :title, :
|
|
438
|
+
add_index :books, :title, unique: true
|
|
374
439
|
end
|
|
375
440
|
|
|
376
441
|
with_auto_validations do
|
|
@@ -390,12 +455,12 @@ describe "Validations" do
|
|
|
390
455
|
context 'within a scope' do
|
|
391
456
|
before do
|
|
392
457
|
ActiveRecord::Schema.define do
|
|
393
|
-
create_table :folders, :
|
|
458
|
+
create_table :folders, force: true do |t|
|
|
394
459
|
t.integer :parent_id
|
|
395
460
|
t.string :name
|
|
396
461
|
end
|
|
397
462
|
|
|
398
|
-
add_index :folders, [:parent_id, :name], :
|
|
463
|
+
add_index :folders, [:parent_id, :name], unique: true
|
|
399
464
|
end
|
|
400
465
|
|
|
401
466
|
with_auto_validations do
|
|
@@ -408,10 +473,10 @@ describe "Validations" do
|
|
|
408
473
|
it "should validate the uniqueness in a case insensitive manner" do
|
|
409
474
|
mixed_case_name = 'Schema Validations'
|
|
410
475
|
parent_folder = Folder.create
|
|
411
|
-
Folder.create(:
|
|
476
|
+
Folder.create(parent: parent_folder, name: mixed_case_name)
|
|
412
477
|
|
|
413
|
-
expect(Folder.new(:
|
|
414
|
-
expect(Folder.new(:
|
|
478
|
+
expect(Folder.new(parent: parent_folder, name: mixed_case_name)).not_to be_valid
|
|
479
|
+
expect(Folder.new(parent: parent_folder, name: mixed_case_name.downcase)).not_to be_valid
|
|
415
480
|
end
|
|
416
481
|
end
|
|
417
482
|
end
|
|
@@ -419,7 +484,7 @@ describe "Validations" do
|
|
|
419
484
|
context 'with optimistic locking' do
|
|
420
485
|
before do
|
|
421
486
|
ActiveRecord::Schema.define do
|
|
422
|
-
create_table :optimistics, :
|
|
487
|
+
create_table :optimistics, force: true do |t|
|
|
423
488
|
t.integer :lock_version
|
|
424
489
|
end
|
|
425
490
|
end
|
|
@@ -448,11 +513,11 @@ describe "Validations" do
|
|
|
448
513
|
|
|
449
514
|
def valid_article_attributes
|
|
450
515
|
{
|
|
451
|
-
:
|
|
452
|
-
:
|
|
453
|
-
:
|
|
454
|
-
:
|
|
455
|
-
:
|
|
516
|
+
title: 'SchemaPlus released!',
|
|
517
|
+
content: "Database matters. Get full use of it but don't write unecessary code. Get SchemaPlus!",
|
|
518
|
+
state: 3,
|
|
519
|
+
average_mark: 9.78,
|
|
520
|
+
active: true
|
|
456
521
|
}
|
|
457
522
|
end
|
|
458
523
|
|