validates_by_schema 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +25 -14
- data/Rakefile +16 -10
- data/lib/validates_by_schema.rb +23 -11
- data/lib/validates_by_schema/validation_option.rb +31 -14
- data/lib/validates_by_schema/version.rb +1 -1
- metadata +40 -40
- data/lib/tasks/validates_by_schema_tasks.rake +0 -4
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 06f3587225760fbc06becf503676ac6b6776d6da
|
4
|
+
data.tar.gz: 08c75f80da3052e73234d051e23fc76b0e4983a6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5051f0bbdb313179827928f0da0fc89e14d19ad7f90f40a5d4208f212b5932707e202f3ed0a0241f4643045ac506e95a09527ed3a8a9ffed52bf4588a4a893c6
|
7
|
+
data.tar.gz: f971d6f9893639ed7e1964f7f8e2d6afb8a6bc7290dbf081565af35853fa44ebb94d0fab949c396ac579025ba3ada1b6cf0c629f57acad2407894c582e372a60
|
data/README.md
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
# Validates By Schema (validates_by_schema)
|
2
|
-
[![
|
3
|
-
[![
|
4
|
-
[![Dependency Status](
|
5
|
-
[![
|
2
|
+
[![Gem Version](http://img.shields.io/gem/v/validates_by_schema.svg?style=flat)](https://rubygems.org/gems/validates_by_schema)
|
3
|
+
[![Build Status](http://img.shields.io/travis/joshwlewis/validates_by_schema.svg?style=flat)](https://travis-ci.org/joshwlewis/validates_by_schema)
|
4
|
+
[![Dependency Status](http://img.shields.io/gemnasium/joshwlewis/validates_by_schema.svg?style=flat)](https://gemnasium.com/joshwlewis/validates_by_schema)
|
5
|
+
[![Coverage Status](http://img.shields.io/coveralls/joshwlewis/validates_by_schema.svg?style=flat)](https://coveralls.io/r/joshwlewis/validates_by_schema)
|
6
|
+
[![Code Climate](http://img.shields.io/codeclimate/github/joshwlewis/validates_by_schema.svg?style=flat)](https://codeclimate.com/github/joshwlewis/validates_by_schema)
|
6
7
|
|
7
8
|
Automatic validation based on your database schema column types and limits. Keep your code DRY by inferring column validations from table properties!
|
8
9
|
|
@@ -11,21 +12,29 @@ Automatic validation based on your database schema column types and limits. Keep
|
|
11
12
|
Say you had a table setup like this:
|
12
13
|
|
13
14
|
```ruby
|
14
|
-
create_table "widgets", :
|
15
|
-
t.integer
|
16
|
-
t.decimal
|
17
|
-
t.string
|
15
|
+
create_table "widgets", force: true do |t|
|
16
|
+
t.integer "quantity", limit: 2, null: false
|
17
|
+
t.decimal "thickness", precision: 4, scale: 4
|
18
|
+
t.string "color", null: false
|
19
|
+
t.boolean "flagged", null: false, default: false
|
20
|
+
t.integer "other_id", null: false
|
18
21
|
end
|
19
22
|
```
|
20
23
|
|
21
24
|
Then these validations are inferred when you add `validates_by_schema` to your model:
|
22
25
|
|
23
26
|
```ruby
|
24
|
-
validates :quantity,
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
27
|
+
validates :quantity, presence: true,
|
28
|
+
numericality: { allow_nil: true,
|
29
|
+
only_integer: true,
|
30
|
+
greater_than: -32768,
|
31
|
+
less_than: 32768}
|
32
|
+
validates :thickness, numericality: { allow_nil: true,
|
33
|
+
less_than_or_equal_to: 0.999,
|
34
|
+
greater_than_or_equal_to: -0.999 }
|
35
|
+
validates :color, presence: true, length: { allow_nil: true, maximum: 255 }
|
36
|
+
validates :flagged, inclusion: { in: [true, false], allow_nil: false }
|
37
|
+
validates :other, presence: true
|
29
38
|
```
|
30
39
|
|
31
40
|
## Installation
|
@@ -58,8 +67,10 @@ validates_by_schema only: [:body, :description]
|
|
58
67
|
validates_by_schema except: [:name, :title]
|
59
68
|
```
|
60
69
|
|
70
|
+
The primary key and timestamp columns are not validated.
|
71
|
+
|
61
72
|
## Notes
|
62
73
|
|
63
74
|
Column properties are inferred by your database adapter (like pg, mysql2, sqlite3), and does not depend on migration files or schema.rb. As such, you could use this on projects where the database where Rails is not in control of the database configuration.
|
64
75
|
|
65
|
-
This has been tested with mysql, postgresql, and sqlite3. It should work with any other database that has reliable adapter.
|
76
|
+
This has been tested with mysql, postgresql, and sqlite3. It should work with any other database that has reliable adapter.
|
data/Rakefile
CHANGED
@@ -20,19 +20,25 @@ RDoc::Task.new(:rdoc) do |rdoc|
|
|
20
20
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
21
|
end
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
23
|
Bundler::GemHelper.install_tasks
|
27
24
|
|
28
|
-
require '
|
25
|
+
require 'rspec/core/rake_task'
|
29
26
|
|
30
|
-
|
31
|
-
t.
|
32
|
-
t.
|
33
|
-
t.pattern = 'test/**/*_test.rb'
|
34
|
-
t.verbose = false
|
27
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
28
|
+
t.pattern = Dir.glob('spec/**/*_spec.rb')
|
29
|
+
t.rspec_opts = ['--backtrace']
|
35
30
|
end
|
36
31
|
|
32
|
+
task default: :spec
|
33
|
+
|
37
34
|
|
38
|
-
|
35
|
+
namespace :db do
|
36
|
+
task :create do
|
37
|
+
case ENV['DB']
|
38
|
+
when'postgresql'
|
39
|
+
exec "psql -c 'create database validates_by_schema_test;' -U postgres"
|
40
|
+
when 'mysql'
|
41
|
+
exec "mysql -e 'create database validates_by_schema_test;'"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/validates_by_schema.rb
CHANGED
@@ -4,27 +4,39 @@ module ValidatesBySchema
|
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
6
|
module ClassMethods
|
7
|
-
|
7
|
+
|
8
|
+
def validates_by_schema(options = {})
|
8
9
|
return unless table_exists?
|
9
|
-
columns = schema_validateable_columns
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
columns.send(v){|c| options[k].include? c.name} if options[k]
|
11
|
+
customized_columns(options).each do |c|
|
12
|
+
ValidationOption.new(self, c).define!
|
14
13
|
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
15
17
|
|
16
|
-
|
17
|
-
|
18
|
-
|
18
|
+
def customized_columns(options)
|
19
|
+
# Allow user to specify :only or :except options
|
20
|
+
schema_validateable_columns.tap do |columns|
|
21
|
+
{ only: :select!, except: :reject! }.each do |k, v|
|
22
|
+
if options[k]
|
23
|
+
attrs = Array(options[k]).collect(&:to_s)
|
24
|
+
columns.send(v) { |c| attrs.include?(c.name) }
|
25
|
+
end
|
26
|
+
end
|
19
27
|
end
|
20
28
|
end
|
21
29
|
|
22
30
|
def schema_validateable_columns
|
23
|
-
|
24
|
-
|
25
|
-
c.primary || %w(updated_at created_at).include?(c.name)
|
31
|
+
columns.reject do |c|
|
32
|
+
ignored_columns_for_validates_by_schema.include?(c.name)
|
26
33
|
end
|
27
34
|
end
|
35
|
+
|
36
|
+
def ignored_columns_for_validates_by_schema
|
37
|
+
[primary_key.to_s, 'created_at', 'updated_at', 'deleted_at']
|
38
|
+
end
|
39
|
+
|
28
40
|
end
|
29
41
|
end
|
30
42
|
|
@@ -1,12 +1,24 @@
|
|
1
1
|
class ValidatesBySchema::ValidationOption
|
2
2
|
# column here must be an ActiveRecord column
|
3
3
|
# i.e. MyARModel.columns.first
|
4
|
-
attr_accessor :column
|
4
|
+
attr_accessor :klass, :column
|
5
5
|
|
6
|
-
def initialize(column)
|
6
|
+
def initialize(klass, column)
|
7
|
+
@klass = klass
|
7
8
|
@column = column
|
8
9
|
end
|
9
10
|
|
11
|
+
def define!
|
12
|
+
if association
|
13
|
+
klass.validates association.name, presence: true unless column.null
|
14
|
+
else
|
15
|
+
options = to_hash
|
16
|
+
klass.validates column.name, options if options.present?
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
10
22
|
def presence?
|
11
23
|
presence && column.type != :boolean
|
12
24
|
end
|
@@ -15,8 +27,12 @@ class ValidatesBySchema::ValidationOption
|
|
15
27
|
!column.null
|
16
28
|
end
|
17
29
|
|
30
|
+
def enum?
|
31
|
+
klass.respond_to?(:defined_enums) && klass.defined_enums.has_key?(column.name)
|
32
|
+
end
|
33
|
+
|
18
34
|
def numericality?
|
19
|
-
[:integer, :decimal, :float].include?
|
35
|
+
[:integer, :decimal, :float].include?(column.type) && !enum?
|
20
36
|
end
|
21
37
|
|
22
38
|
def numericality
|
@@ -27,11 +43,11 @@ class ValidatesBySchema::ValidationOption
|
|
27
43
|
numericality[:less_than] = integer_max
|
28
44
|
numericality[:greater_than] = -integer_max
|
29
45
|
end
|
30
|
-
elsif column.type == :decimal
|
46
|
+
elsif column.type == :decimal && decimal_max
|
31
47
|
numericality[:less_than_or_equal_to] = decimal_max
|
32
48
|
numericality[:greater_than_or_equal_to] = -decimal_max
|
33
49
|
end
|
34
|
-
numericality[:allow_nil] =
|
50
|
+
numericality[:allow_nil] = true
|
35
51
|
numericality
|
36
52
|
end
|
37
53
|
|
@@ -40,7 +56,7 @@ class ValidatesBySchema::ValidationOption
|
|
40
56
|
end
|
41
57
|
|
42
58
|
def length
|
43
|
-
{:
|
59
|
+
{ maximum: column.limit, allow_nil: true }
|
44
60
|
end
|
45
61
|
|
46
62
|
def inclusion?
|
@@ -48,23 +64,25 @@ class ValidatesBySchema::ValidationOption
|
|
48
64
|
end
|
49
65
|
|
50
66
|
def inclusion
|
51
|
-
{:
|
67
|
+
{ in: [true, false], allow_nil: column.null }
|
52
68
|
end
|
53
69
|
|
54
70
|
def integer_max
|
55
|
-
(2
|
71
|
+
(2**(8 * column.limit)) / 2 if column.limit
|
56
72
|
end
|
57
73
|
|
58
74
|
def decimal_max
|
59
|
-
10.0**(column.precision-column.scale) - 10.0**(-column.scale)
|
75
|
+
10.0**(column.precision - column.scale) - 10.0**(-column.scale) if column.precision && column.scale
|
60
76
|
end
|
61
77
|
|
62
|
-
def
|
63
|
-
|
78
|
+
def association
|
79
|
+
@association ||= klass.reflect_on_all_associations(:belongs_to).find do |a|
|
80
|
+
a.foreign_key.to_s == column.name
|
81
|
+
end
|
64
82
|
end
|
65
83
|
|
66
84
|
def to_hash
|
67
|
-
[:presence, :numericality, :length, :inclusion].inject({}) do |h,k|
|
85
|
+
[:presence, :numericality, :length, :inclusion].inject({}) do |h, k|
|
68
86
|
send(:"#{k}?") ? h.merge(k => send(k)) : h
|
69
87
|
end
|
70
88
|
end
|
@@ -72,5 +90,4 @@ class ValidatesBySchema::ValidationOption
|
|
72
90
|
def to_s
|
73
91
|
to_hash.inspect
|
74
92
|
end
|
75
|
-
|
76
|
-
end
|
93
|
+
end
|
metadata
CHANGED
@@ -1,110 +1,112 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: validates_by_schema
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.3.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Josh Lewis
|
8
|
+
- Pascal Zumkehr
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2015-09-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
15
|
+
name: activerecord
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
17
|
requirements:
|
19
|
-
- -
|
18
|
+
- - ">="
|
20
19
|
- !ruby/object:Gem::Version
|
21
20
|
version: 3.1.0
|
22
21
|
type: :runtime
|
23
22
|
prerelease: false
|
24
23
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
24
|
requirements:
|
27
|
-
- -
|
25
|
+
- - ">="
|
28
26
|
- !ruby/object:Gem::Version
|
29
27
|
version: 3.1.0
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rake
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
30
42
|
- !ruby/object:Gem::Dependency
|
31
43
|
name: rspec-rails
|
32
44
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
45
|
requirements:
|
35
|
-
- -
|
46
|
+
- - ">="
|
36
47
|
- !ruby/object:Gem::Version
|
37
48
|
version: '0'
|
38
49
|
type: :development
|
39
50
|
prerelease: false
|
40
51
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
52
|
requirements:
|
43
|
-
- -
|
53
|
+
- - ">="
|
44
54
|
- !ruby/object:Gem::Version
|
45
55
|
version: '0'
|
46
56
|
- !ruby/object:Gem::Dependency
|
47
57
|
name: shoulda-matchers
|
48
58
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
59
|
requirements:
|
51
|
-
- -
|
60
|
+
- - ">="
|
52
61
|
- !ruby/object:Gem::Version
|
53
62
|
version: '0'
|
54
63
|
type: :development
|
55
64
|
prerelease: false
|
56
65
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
66
|
requirements:
|
59
|
-
- -
|
67
|
+
- - ">="
|
60
68
|
- !ruby/object:Gem::Version
|
61
69
|
version: '0'
|
62
70
|
- !ruby/object:Gem::Dependency
|
63
71
|
name: sqlite3
|
64
72
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
73
|
requirements:
|
67
|
-
- -
|
74
|
+
- - ">="
|
68
75
|
- !ruby/object:Gem::Version
|
69
76
|
version: '0'
|
70
77
|
type: :development
|
71
78
|
prerelease: false
|
72
79
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
80
|
requirements:
|
75
|
-
- -
|
81
|
+
- - ">="
|
76
82
|
- !ruby/object:Gem::Version
|
77
83
|
version: '0'
|
78
84
|
- !ruby/object:Gem::Dependency
|
79
85
|
name: pg
|
80
86
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
87
|
requirements:
|
83
|
-
- -
|
88
|
+
- - ">="
|
84
89
|
- !ruby/object:Gem::Version
|
85
90
|
version: '0'
|
86
91
|
type: :development
|
87
92
|
prerelease: false
|
88
93
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
94
|
requirements:
|
91
|
-
- -
|
95
|
+
- - ">="
|
92
96
|
- !ruby/object:Gem::Version
|
93
97
|
version: '0'
|
94
98
|
- !ruby/object:Gem::Dependency
|
95
99
|
name: mysql2
|
96
100
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
101
|
requirements:
|
99
|
-
- -
|
102
|
+
- - ">="
|
100
103
|
- !ruby/object:Gem::Version
|
101
104
|
version: '0'
|
102
105
|
type: :development
|
103
106
|
prerelease: false
|
104
107
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
108
|
requirements:
|
107
|
-
- -
|
109
|
+
- - ">="
|
108
110
|
- !ruby/object:Gem::Version
|
109
111
|
version: '0'
|
110
112
|
description: Keep your code DRY by inferring column validations from table properties!
|
@@ -112,40 +114,38 @@ description: Keep your code DRY by inferring column validations from table prope
|
|
112
114
|
backed columns.
|
113
115
|
email:
|
114
116
|
- josh.w.lewis@gmail.com
|
117
|
+
- pascal@codez.ch
|
115
118
|
executables: []
|
116
119
|
extensions: []
|
117
120
|
extra_rdoc_files: []
|
118
121
|
files:
|
119
|
-
- lib/tasks/validates_by_schema_tasks.rake
|
120
|
-
- lib/validates_by_schema/validation_option.rb
|
121
|
-
- lib/validates_by_schema/version.rb
|
122
|
-
- lib/validates_by_schema.rb
|
123
122
|
- MIT-LICENSE
|
124
|
-
- Rakefile
|
125
123
|
- README.md
|
124
|
+
- Rakefile
|
125
|
+
- lib/validates_by_schema.rb
|
126
|
+
- lib/validates_by_schema/validation_option.rb
|
127
|
+
- lib/validates_by_schema/version.rb
|
126
128
|
homepage: http://github.com/joshwlewis/validates_by_schema
|
127
129
|
licenses: []
|
130
|
+
metadata: {}
|
128
131
|
post_install_message:
|
129
132
|
rdoc_options: []
|
130
133
|
require_paths:
|
131
134
|
- lib
|
132
135
|
required_ruby_version: !ruby/object:Gem::Requirement
|
133
|
-
none: false
|
134
136
|
requirements:
|
135
|
-
- -
|
137
|
+
- - ">="
|
136
138
|
- !ruby/object:Gem::Version
|
137
139
|
version: '0'
|
138
140
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
139
|
-
none: false
|
140
141
|
requirements:
|
141
|
-
- -
|
142
|
+
- - ">="
|
142
143
|
- !ruby/object:Gem::Version
|
143
144
|
version: '0'
|
144
145
|
requirements: []
|
145
146
|
rubyforge_project:
|
146
|
-
rubygems_version:
|
147
|
+
rubygems_version: 2.4.5.1
|
147
148
|
signing_key:
|
148
|
-
specification_version:
|
149
|
+
specification_version: 4
|
149
150
|
summary: Automatic validation based on your database schema column types and limits.
|
150
151
|
test_files: []
|
151
|
-
has_rdoc:
|