model_validator 1.2.0 → 1.2.1
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 +4 -4
- data/.travis.yml +1 -0
- data/Gemfile.lock +1 -1
- data/Makefile +1 -0
- data/README.md +10 -9
- data/lib/model_validator.rb +3 -66
- data/lib/model_validator/log_handler.rb +16 -0
- data/lib/model_validator/stats_handler.rb +25 -0
- data/lib/model_validator/validator.rb +30 -0
- data/lib/model_validator/version.rb +1 -1
- data/rakelib/release.rake +1 -12
- data/rakelib/release/release.rb +14 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f891705a9cd1d3195f54ba04d7d1a4634fb921527dd2472975d249ad43835fab
|
4
|
+
data.tar.gz: b133ec1cbdbb89c9b43d42871dd65cbbc2baa614f776b89ce5b5cae545bd21f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 54adca12ba9576cb7b12eea53cdd04717dabc3dfc2bb494a8fae30ae664453b75707f3929fabd37a0f32f324b0d9dd32af351e0394716e3ac2f544b2f6529ba5
|
7
|
+
data.tar.gz: 63e5029d404976f34008d2e9bc5dc5713dd7ba26681c3e8bb8fa76567c3b5dbab4acfcc7146da67340b7a66566b57008f7ef435ca7c3e5a40f3dcbe8050aad33
|
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
data/Makefile
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
[](https://www.travis-ci.com/jibidus/model_validator)
|
2
2
|
[](https://coveralls.io/github/jibidus/model_validation?branch=main)
|
3
|
+
[](https://badge.fury.io/rb/model_validator)
|
3
4
|
|
4
5
|
# model_validator
|
5
6
|
|
@@ -15,16 +16,16 @@ This is useful since error may occur when manipulating such data.
|
|
15
16
|
|
16
17
|
It is recommended to use this gem during deployment step:
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
1. restore production database in a staging/preprod/non-production environment
|
20
|
+
2. validate the database
|
21
|
+
3. add missing migrations in case of violations
|
22
|
+
4. repeat validation and fix until there is no more violation
|
23
|
+
5. then, you are ready to deploy your application in production
|
23
24
|
|
24
25
|
## Limitations
|
25
26
|
|
26
27
|
This gem fetch **all** record in database, and, for each record run the Active Record validation.
|
27
|
-
So, because of performances reason, this
|
28
|
+
So, because of performances reason, this may be only acceptable for tiny databases (thousand of records).
|
28
29
|
|
29
30
|
## Installation
|
30
31
|
|
@@ -92,8 +93,8 @@ Many already existing gems may do the same, but none are satisfying:
|
|
92
93
|
|
93
94
|
- [validb](https://github.com/jgeiger/validb): depends on [sidekiq](https://github.com/mperham/sidekiq)
|
94
95
|
- [validates_blacklist](https://www.rubydoc.info/gems/validates_blacklist/0.0.1): requires to add configuration in each model 😨
|
95
|
-
- [valid_items](https://rubygems.org/gems/valid_items):
|
96
|
-
- [schema-validations](https://github.com/robworley/schema-validations): I
|
96
|
+
- [valid_items](https://rubygems.org/gems/valid_items): not compliant with rails 6 + cannot find sources to contribute
|
97
|
+
- [schema-validations](https://github.com/robworley/schema-validations): I didn't understand what it really does 🤪
|
97
98
|
|
98
99
|
## Contributing
|
99
100
|
|
data/lib/model_validator.rb
CHANGED
@@ -1,23 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "rails"
|
4
|
+
require "./lib/model_validator/stats_handler"
|
5
|
+
require "./lib/model_validator/log_handler"
|
6
|
+
require "./lib/model_validator/validator"
|
4
7
|
|
5
8
|
# Validate models in database according Active Record model validation rules
|
6
9
|
module ModelValidator
|
7
10
|
require "model_validator/railtie" if defined?(Rails)
|
8
11
|
|
9
|
-
# Validations summary, with:
|
10
|
-
# - violations: number of violations (i.e. number of model which validation failed)
|
11
|
-
# - total: total number of validated models
|
12
|
-
class Result
|
13
|
-
attr_accessor :violations, :total
|
14
|
-
|
15
|
-
def initialize(violations: 0, total: 0)
|
16
|
-
@violations = violations
|
17
|
-
@total = total
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
12
|
def self.validate_all(skipped_models: [])
|
22
13
|
if skipped_models.empty?
|
23
14
|
Rails.logger.info "No model skipped"
|
@@ -29,58 +20,4 @@ module ModelValidator
|
|
29
20
|
Validator.new(handlers: handlers, skip_models: skipped_models).run
|
30
21
|
stats_handler.result
|
31
22
|
end
|
32
|
-
|
33
|
-
# Validation engine, which fetch, and validate each database records
|
34
|
-
class Validator
|
35
|
-
def initialize(handlers: [], skip_models: [])
|
36
|
-
@handlers = handlers
|
37
|
-
@skip_models = skip_models
|
38
|
-
end
|
39
|
-
|
40
|
-
def classes_to_validate
|
41
|
-
ActiveRecord::Base.subclasses
|
42
|
-
.reject { |type| type.to_s.include? "::" } # subclassed classes are not our own models
|
43
|
-
.reject { |type| @skip_models.include? type }
|
44
|
-
end
|
45
|
-
|
46
|
-
def run
|
47
|
-
classes_to_validate.each do |model_class|
|
48
|
-
@handlers.each { |h| h.try(:on_new_class, model_class) }
|
49
|
-
model_class.unscoped.find_each do |model|
|
50
|
-
@handlers.each { |h| h.try(:on_violation, model) } unless model.valid?
|
51
|
-
@handlers.each { |h| h.try(:after_validation, model) }
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
# This handler logs validation progression
|
58
|
-
class LogHandler
|
59
|
-
def on_new_class(model_class)
|
60
|
-
Rails.logger.info "Checking #{model_class.count} #{model_class}…"
|
61
|
-
end
|
62
|
-
|
63
|
-
def on_violation(model)
|
64
|
-
Rails.logger.error "#<#{model.class} id: #{model.id}, errors: #{model.errors.full_messages}>" unless model.valid?
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
# This handler computes validation statistics
|
69
|
-
class StatsHandler
|
70
|
-
attr_reader :result
|
71
|
-
|
72
|
-
def initialize
|
73
|
-
@result = Result.new(violations: 0, total: 0)
|
74
|
-
end
|
75
|
-
|
76
|
-
def on_new_class(_) end
|
77
|
-
|
78
|
-
def on_violation(_)
|
79
|
-
@result.violations += 1
|
80
|
-
end
|
81
|
-
|
82
|
-
def after_validation(_)
|
83
|
-
@result.total += 1
|
84
|
-
end
|
85
|
-
end
|
86
23
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails"
|
4
|
+
|
5
|
+
module ModelValidator
|
6
|
+
# This handler logs validation progression
|
7
|
+
class LogHandler
|
8
|
+
def on_new_class(model_class)
|
9
|
+
Rails.logger.info "Checking #{model_class.count} #{model_class}…"
|
10
|
+
end
|
11
|
+
|
12
|
+
def on_violation(model)
|
13
|
+
Rails.logger.error "#<#{model.class} id: #{model.id}, errors: #{model.errors.full_messages}>" unless model.valid?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ModelValidator
|
4
|
+
# Validations summary, with:
|
5
|
+
# - violations: number of violations (i.e. number of model which validation failed)
|
6
|
+
# - total: total number of validated models
|
7
|
+
Result = Struct.new(:violations, :total)
|
8
|
+
|
9
|
+
# This handler computes validation statistics
|
10
|
+
class StatsHandler
|
11
|
+
attr_reader :result
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@result = Result.new(0, 0)
|
15
|
+
end
|
16
|
+
|
17
|
+
def on_violation(_)
|
18
|
+
@result.violations += 1
|
19
|
+
end
|
20
|
+
|
21
|
+
def after_validation(_)
|
22
|
+
@result.total += 1
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails"
|
4
|
+
|
5
|
+
module ModelValidator
|
6
|
+
# Validation engine, which fetch, and validate each database records
|
7
|
+
class Validator
|
8
|
+
def initialize(handlers: [], skip_models: [])
|
9
|
+
@handlers = handlers
|
10
|
+
@skip_models = skip_models
|
11
|
+
end
|
12
|
+
|
13
|
+
def classes_to_validate
|
14
|
+
ActiveRecord::Base.descendants
|
15
|
+
.reject(&:abstract_class)
|
16
|
+
.select { |type| type.subclasses.empty? }
|
17
|
+
.reject { |type| @skip_models.include? type }
|
18
|
+
end
|
19
|
+
|
20
|
+
def run
|
21
|
+
classes_to_validate.each do |model_class|
|
22
|
+
@handlers.each { |h| h.try(:on_new_class, model_class) }
|
23
|
+
model_class.unscoped.find_each do |model|
|
24
|
+
@handlers.each { |h| h.try(:on_violation, model) } unless model.valid?
|
25
|
+
@handlers.each { |h| h.try(:after_validation, model) }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/rakelib/release.rake
CHANGED
@@ -18,20 +18,9 @@ namespace :release do
|
|
18
18
|
puts "---------------------------------------------------------------------"
|
19
19
|
puts release.changelog
|
20
20
|
puts "---------------------------------------------------------------------"
|
21
|
-
|
22
21
|
next if args[:dry_run]
|
23
22
|
|
24
23
|
release.git_commit!
|
25
|
-
|
26
|
-
puts <<~MSG
|
27
|
-
Release built.
|
28
|
-
|
29
|
-
Run following commands to publish version #{release.new_version}:
|
30
|
-
$> git push && git push --tags
|
31
|
-
$> bundle exec rake release
|
32
|
-
|
33
|
-
After that, do not forget to report changelog in Github Releases page:
|
34
|
-
https://github.com/jibidus/model_validator/releases
|
35
|
-
MSG
|
24
|
+
puts release.publishing_instructions
|
36
25
|
end
|
37
26
|
end
|
data/rakelib/release/release.rb
CHANGED
@@ -54,6 +54,20 @@ class Release
|
|
54
54
|
`git commit -m ":label: release version #{new_version}"`
|
55
55
|
end
|
56
56
|
|
57
|
+
def publishing_instructions
|
58
|
+
<<~MSG
|
59
|
+
New commit created with the release.
|
60
|
+
|
61
|
+
Run following commands to publish version #{new_version}:
|
62
|
+
$> git push
|
63
|
+
$> bundle exec rake release
|
64
|
+
|
65
|
+
Then edit tag with changelog:
|
66
|
+
$> git tag v#{new_version} -f -a
|
67
|
+
$> git push -f --tags
|
68
|
+
MSG
|
69
|
+
end
|
70
|
+
|
57
71
|
private
|
58
72
|
|
59
73
|
def sub_file_content(file_path, from, to)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: model_validator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jibidus
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-02-
|
11
|
+
date: 2021-02-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -158,8 +158,11 @@ files:
|
|
158
158
|
- Rakefile
|
159
159
|
- lib/model_validator.rb
|
160
160
|
- lib/model_validator/Rakefile
|
161
|
+
- lib/model_validator/log_handler.rb
|
161
162
|
- lib/model_validator/railtie.rb
|
163
|
+
- lib/model_validator/stats_handler.rb
|
162
164
|
- lib/model_validator/tasks/db/validate.rake
|
165
|
+
- lib/model_validator/validator.rb
|
163
166
|
- lib/model_validator/version.rb
|
164
167
|
- model_validator.gemspec
|
165
168
|
- rakelib/release.rake
|