codez-validates_by_schema 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NmU4ZTkyMzRhOWI4MWQxMGFhZGE1NTZlOWQyM2VmODA2ZDkwYzY4Nw==
5
+ data.tar.gz: !binary |-
6
+ MjZhMWQ2ZDYxM2I4NmNmYTc5NDEzYWZkYjE4NjZjYzE2ODM2ZGQwYw==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ YWJjM2FmYTEyZmE5Yzc4M2FjMjQzMjA3ZTU3N2RhMDc0ZGRmMzI3OWQyY2Fl
10
+ ZjQzYTEwZDgxOWI0MTA4MDJjNTgzMTA4NGVhMGFkM2YxZjk1ZGY3ZjE1Y2Nm
11
+ YWI4ZWUxNWM3YmVjZjg1ZmY0YTdlYjJmZGViNjM5MjY5NjhmNWY=
12
+ data.tar.gz: !binary |-
13
+ MTMyNGQwYWEwNTM2Y2M5ZTVlZmE2NDBjNTA5OWY2NjdlYzU0MDgzYjFmMjE3
14
+ OTg3ZDI3MWE5NGM2ODg4YjdhYTNjMDFkOTg4MjlkOGQ1ODY4MTg3NGUwN2Q4
15
+ ZjkyNTM2YTY4Y2VkYWM3Yjg0MmI4YmY5YWQ3NzI0NDg0YjIxZjY=
@@ -0,0 +1,20 @@
1
+ Copyright 2012 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,65 @@
1
+ # Validates By Schema (validates_by_schema)
2
+ [![Build Status](https://secure.travis-ci.org/joshwlewis/validates_by_schema.png)](http://travis-ci.org/joshwlewis/validates_by_schema)
3
+ [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/joshwlewis/validates_by_schema)
4
+ [![Dependency Status](https://gemnasium.com/joshwlewis/validates_by_schema.png)](https://gemnasium.com/joshwlewis/validates_by_schema)
5
+ [![Gem Version](https://badge.fury.io/rb/validates_by_schema.png)](http://badge.fury.io/rb/validates_by_schema)
6
+
7
+ Automatic validation based on your database schema column types and limits. Keep your code DRY by inferring column validations from table properties!
8
+
9
+ ## Example
10
+
11
+ Say you had a table setup like this:
12
+
13
+ ```ruby
14
+ create_table "widgets", :force => true do |t|
15
+ t.integer "quantity", :limit => 2
16
+ t.decimal "thickness", :precision => 4, :scale => 4
17
+ t.string "color", :null => false
18
+ end
19
+ ```
20
+
21
+ Then these validations are inferred when you add `validates_by_schema` to your model:
22
+
23
+ ```ruby
24
+ validates :quantity, numericality: { allow_nil: true,
25
+ greater_than: -32768, less_than: 32768}
26
+ validates :thickness, numericality: {allow_nil: true,
27
+ less_than_or_equal_to: 0.999, greater_than_or_equal_to: -0.999}
28
+ validates :color, presence: true, length: {allow_nil: false, maximum: 255}
29
+ ```
30
+
31
+ ## Installation
32
+
33
+ 1. Add it to your Gemfile:
34
+
35
+ ```ruby
36
+ gem "validates_by_schema"
37
+ ```
38
+
39
+ 2. Then `bundle`
40
+
41
+ 3. Call it from your ActiveRecord model:
42
+
43
+ ```ruby
44
+ class Widget < ActiveRecord::Base
45
+ validates_by_schema
46
+ end
47
+ ```
48
+
49
+ ## Usage
50
+
51
+ You can also whitelist or blacklist columns with :only or :except options, respectively:
52
+
53
+ ```ruby
54
+ validates_by_schema only: [:body, :description]
55
+ ```
56
+
57
+ ```ruby
58
+ validates_by_schema except: [:name, :title]
59
+ ```
60
+
61
+ ## Notes
62
+
63
+ 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
+
65
+ This has been tested with mysql, postgresql, and sqlite3. It should work with any other database that has reliable adapter.
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'ValidatesBySchema'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ Bundler::GemHelper.install_tasks
24
+
25
+ require 'rspec/core/rake_task'
26
+
27
+ RSpec::Core::RakeTask.new(:spec) do |t|
28
+ t.pattern = Dir.glob('spec/**/*_spec.rb')
29
+ t.rspec_opts = ['--backtrace']
30
+ end
31
+
32
+ task default: :spec
33
+
34
+
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
@@ -0,0 +1,61 @@
1
+ module ValidatesBySchema
2
+ autoload :ValidationOption, 'validates_by_schema/validation_option'
3
+
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+ def validates_by_schema(options = {})
8
+ return unless table_exists?
9
+
10
+ columns = schema_validateable_columns
11
+ customize_columns(columns, options)
12
+ define_validations(columns)
13
+ define_association_validations
14
+ end
15
+
16
+ def schema_validateable_columns
17
+ # Don't auto validate primary, foreign keys or timestamps
18
+ foreign_keys = all_foreign_keys
19
+ columns.reject do |c|
20
+ c.name == primary_key.to_s ||
21
+ %w(updated_at created_at).include?(c.name) ||
22
+ foreign_keys.include?(c.name)
23
+ end
24
+ end
25
+
26
+ def customize_columns(columns, options)
27
+ # Allow user to specify :only or :except options
28
+ { only: :select!, except: :reject! }.each do |k, v|
29
+ if options[k]
30
+ attrs = Array(options[k]).collect(&:to_s)
31
+ columns.send(v) { |c| attrs.include?(c.name) }
32
+ end
33
+ end
34
+ end
35
+
36
+ def define_validations(columns)
37
+ columns.each do |c|
38
+ vo = ValidationOption.new(c).to_hash
39
+ validates c.name, vo if vo.present?
40
+ end
41
+ end
42
+
43
+ def define_association_validations
44
+ reflect_on_all_associations(:belongs_to).each do |association|
45
+ column = columns_hash[association.foreign_key.to_s]
46
+ next unless column
47
+ validates association.name, presence: true unless column.null
48
+ end
49
+ end
50
+
51
+ def all_foreign_keys
52
+ reflect_on_all_associations(:belongs_to).collect do |association|
53
+ association.foreign_key.to_s
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ ActiveSupport.on_load :active_record do
60
+ include ValidatesBySchema
61
+ end
@@ -0,0 +1,71 @@
1
+ class ValidatesBySchema::ValidationOption
2
+ # column here must be an ActiveRecord column
3
+ # i.e. MyARModel.columns.first
4
+ attr_accessor :column
5
+
6
+ def initialize(column)
7
+ @column = column
8
+ end
9
+
10
+ def presence?
11
+ presence && column.type != :boolean
12
+ end
13
+
14
+ def presence
15
+ !column.null
16
+ end
17
+
18
+ def numericality?
19
+ [:integer, :decimal, :float].include? column.type
20
+ end
21
+
22
+ def numericality
23
+ numericality = {}
24
+ if column.type == :integer
25
+ numericality[:only_integer] = true
26
+ if integer_max
27
+ numericality[:less_than] = integer_max
28
+ numericality[:greater_than] = -integer_max
29
+ end
30
+ elsif column.type == :decimal
31
+ numericality[:less_than_or_equal_to] = decimal_max
32
+ numericality[:greater_than_or_equal_to] = -decimal_max
33
+ end
34
+ numericality[:allow_nil] = true
35
+ numericality
36
+ end
37
+
38
+ def length?
39
+ [:string, :text].include?(column.type) && column.limit
40
+ end
41
+
42
+ def length
43
+ { maximum: column.limit, allow_nil: true }
44
+ end
45
+
46
+ def inclusion?
47
+ column.type == :boolean
48
+ end
49
+
50
+ def inclusion
51
+ { in: [true, false], allow_nil: column.null }
52
+ end
53
+
54
+ def integer_max
55
+ (2**(8 * column.limit)) / 2 if column.limit
56
+ end
57
+
58
+ def decimal_max
59
+ 10.0**(column.precision - column.scale) - 10.0**(-column.scale)
60
+ end
61
+
62
+ def to_hash
63
+ [:presence, :numericality, :length, :inclusion].inject({}) do |h, k|
64
+ send(:"#{k}?") ? h.merge(k => send(k)) : h
65
+ end
66
+ end
67
+
68
+ def to_s
69
+ to_hash.inspect
70
+ end
71
+ end
@@ -0,0 +1,3 @@
1
+ module ValidatesBySchema
2
+ VERSION = '0.3.0'
3
+ end
metadata ADDED
@@ -0,0 +1,151 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: codez-validates_by_schema
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Josh Lewis
8
+ - Pascal Zumkehr
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-08-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activerecord
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ! '>='
19
+ - !ruby/object:Gem::Version
20
+ version: 3.1.0
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ! '>='
26
+ - !ruby/object:Gem::Version
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'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec-rails
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: shoulda-matchers
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: sqlite3
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ! '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: pg
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ! '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ! '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: mysql2
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ! '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ description: Keep your code DRY by inferring column validations from table properties!
113
+ Automagically validate presence, length, numericality, and inclusion of ActiveRecord
114
+ backed columns.
115
+ email:
116
+ - josh.w.lewis@gmail.com
117
+ - spam@codez.ch
118
+ executables: []
119
+ extensions: []
120
+ extra_rdoc_files: []
121
+ files:
122
+ - MIT-LICENSE
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
128
+ homepage: http://github.com/codez/validates_by_schema
129
+ licenses: []
130
+ metadata: {}
131
+ post_install_message:
132
+ rdoc_options: []
133
+ require_paths:
134
+ - lib
135
+ required_ruby_version: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ! '>='
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ required_rubygems_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ! '>='
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ requirements: []
146
+ rubyforge_project:
147
+ rubygems_version: 2.4.3
148
+ signing_key:
149
+ specification_version: 4
150
+ summary: Automatic validation based on your database schema column types and limits.
151
+ test_files: []