valhammer 0.2.2 → 0.3.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/.simplecov +1 -3
- data/README.md +29 -2
- data/lib/valhammer/validations.rb +45 -18
- data/lib/valhammer/version.rb +1 -1
- data/spec/db/schema.rb +1 -1
- data/spec/lib/valhammer/validations_spec.rb +74 -37
- data/valhammer.gemspec +1 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 758eec1c687a507398055fdb46d849004962b1b6
|
4
|
+
data.tar.gz: bda97ef82eb60f40da4789514710c122897a35ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6a8dc0e51c7b2ebb78fc0a6536be61a49a7b66257807f6dd901e28736631b755c7fdebd4639d350780862af0f8de2fce2846b7a1e55566b435aaee018e1c83a7
|
7
|
+
data.tar.gz: af035d6d7dab4931dbbabe1fa1602b30fd98610e90b2ec46f8a631749b4ae734caf1774afec8f7f57f495602a6c68a1a534ca7d7aa5466713303630c06a42c89
|
data/.simplecov
CHANGED
data/README.md
CHANGED
@@ -82,13 +82,40 @@ Generated validations are:
|
|
82
82
|
* `:length` — added to `string` columns to ensure the value fits in the
|
83
83
|
column
|
84
84
|
|
85
|
-
|
85
|
+
### Disabling Validators
|
86
|
+
|
87
|
+
Passing a block to `valhammer` allows some selective calls to `disable` to
|
88
|
+
customise the validators which are applied to your model:
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
class Widget < ActiveRecord::Base
|
92
|
+
valhammer do
|
93
|
+
disable item_code: [:presence, :uniqueness]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
```
|
97
|
+
|
98
|
+
Disabling an attribute instructs Valhammer not to apply *any* validators for
|
99
|
+
that attribute:
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
class Widget < ActiveRecord::Base
|
103
|
+
valhammer do
|
104
|
+
disable :supplier_code
|
105
|
+
end
|
106
|
+
end
|
107
|
+
```
|
108
|
+
|
109
|
+
When disabling validations for an association, disable the validations on the
|
110
|
+
**association name**, not the name of the foreign key column:
|
86
111
|
|
87
112
|
```ruby
|
88
113
|
class Widget < ActiveRecord::Base
|
89
114
|
belongs_to :supplier
|
90
115
|
|
91
|
-
valhammer
|
116
|
+
valhammer do
|
117
|
+
disable supplier: :presence
|
118
|
+
end
|
92
119
|
end
|
93
120
|
```
|
94
121
|
|
@@ -1,37 +1,68 @@
|
|
1
1
|
module Valhammer
|
2
2
|
module Validations
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
class DisabledFieldConfig
|
4
|
+
def self.perform(&bl)
|
5
|
+
new.tap { |obj| obj.instance_eval(&bl) if block_given? }.to_opts
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@disabled_validations = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
ALL = %i(presence uniqueness inclusion length numericality).freeze
|
13
|
+
|
14
|
+
def disable(opts)
|
15
|
+
opts = { opts => ALL } if opts.is_a?(Symbol)
|
16
|
+
|
17
|
+
opts.each do |k, v|
|
18
|
+
@disabled_validations[k] ||= []
|
19
|
+
@disabled_validations[k] += Array(v)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_opts
|
24
|
+
@disabled_validations.stringify_keys.transform_values do |v|
|
25
|
+
Hash[v.zip(Array.new(v.length, false))]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
6
29
|
|
7
30
|
VALHAMMER_EXCLUDED_FIELDS = %w(created_at updated_at).freeze
|
8
31
|
|
9
|
-
private_constant :
|
32
|
+
private_constant :VALHAMMER_EXCLUDED_FIELDS, :DisabledFieldConfig
|
10
33
|
|
11
|
-
def valhammer(
|
34
|
+
def valhammer(&bl)
|
12
35
|
@valhammer_indexes = connection.indexes(table_name)
|
13
|
-
|
36
|
+
config = DisabledFieldConfig.perform(&bl)
|
37
|
+
|
14
38
|
columns_hash.each do |name, column|
|
15
|
-
valhammer_validate(name, column,
|
39
|
+
valhammer_validate(name, column, config)
|
16
40
|
end
|
17
41
|
end
|
18
42
|
|
19
43
|
private
|
20
44
|
|
21
|
-
def valhammer_validate(name, column,
|
45
|
+
def valhammer_validate(name, column, config)
|
22
46
|
return if valhammer_exclude?(name)
|
23
47
|
|
24
48
|
assoc_name = valhammer_assoc_name(name)
|
25
|
-
if assoc_name
|
26
|
-
validations = valhammer_validations(column, opts)
|
27
|
-
validates(name, validations) unless validations.empty?
|
28
|
-
return
|
29
|
-
end
|
49
|
+
return valhammer_validate_assoc(assoc_name, column, config) if assoc_name
|
30
50
|
|
51
|
+
opts = valhammer_field_config(config, name)
|
52
|
+
validations = valhammer_validations(column, opts)
|
53
|
+
validates(name, validations) unless validations.empty?
|
54
|
+
end
|
55
|
+
|
56
|
+
def valhammer_validate_assoc(assoc_name, column, config)
|
57
|
+
opts = valhammer_field_config(config, assoc_name)
|
31
58
|
return if column.null || !opts[:presence]
|
32
59
|
validates(assoc_name, presence: true)
|
33
60
|
end
|
34
61
|
|
62
|
+
def valhammer_field_config(config, field)
|
63
|
+
Hash.new(true).merge(config[field.to_s] || {})
|
64
|
+
end
|
65
|
+
|
35
66
|
def valhammer_validations(column, opts)
|
36
67
|
logger.debug("Valhammer generating options for #{valhammer_info(column)}")
|
37
68
|
|
@@ -66,7 +97,6 @@ module Valhammer
|
|
66
97
|
return unless unique_keys.one?
|
67
98
|
|
68
99
|
scope = unique_keys.first.columns[0..-2]
|
69
|
-
|
70
100
|
validations[:uniqueness] = valhammer_unique_opts(scope)
|
71
101
|
end
|
72
102
|
|
@@ -80,9 +110,7 @@ module Valhammer
|
|
80
110
|
end
|
81
111
|
|
82
112
|
def valhammer_numeric(validations, column, opts)
|
83
|
-
return
|
84
|
-
|
85
|
-
return if defined_enums.key?(column.name)
|
113
|
+
return if !opts[:numericality] || defined_enums.key?(column.name)
|
86
114
|
|
87
115
|
case column.type
|
88
116
|
when :integer
|
@@ -96,7 +124,6 @@ module Valhammer
|
|
96
124
|
|
97
125
|
def valhammer_length(validations, column, opts)
|
98
126
|
return unless opts[:length] && column.type == :string && column.limit
|
99
|
-
|
100
127
|
validations[:length] = { maximum: column.limit }
|
101
128
|
end
|
102
129
|
|
data/lib/valhammer/version.rb
CHANGED
data/spec/db/schema.rb
CHANGED
@@ -4,7 +4,7 @@ ActiveRecord::Schema.define(version: 0) do
|
|
4
4
|
|
5
5
|
t.string :name, null: false, default: nil, limit: 100
|
6
6
|
t.string :mail, null: false, default: nil
|
7
|
-
t.string :identifier, null: false, default: nil
|
7
|
+
t.string :identifier, null: false, default: nil, limit: 100
|
8
8
|
t.string :description, null: true, default: nil
|
9
9
|
t.integer :age, null: true, default: nil
|
10
10
|
t.decimal :gpa, null: false, default: 3.0
|
@@ -180,77 +180,114 @@ RSpec.describe Valhammer::Validations do
|
|
180
180
|
it { is_expected.to include(a_validator_for(:name, :length, maximum: 100)) }
|
181
181
|
end
|
182
182
|
|
183
|
-
context '
|
184
|
-
around do |example|
|
185
|
-
old = ActiveRecord::Base.logger
|
186
|
-
|
187
|
-
begin
|
188
|
-
ActiveRecord::Base.logger = Logger.new('/dev/null')
|
189
|
-
example.run
|
190
|
-
ensure
|
191
|
-
ActiveRecord::Base.logger = old
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
183
|
+
context 'when passing a block' do
|
195
184
|
let(:klass) do
|
196
|
-
opts =
|
185
|
+
opts = disable_opts
|
186
|
+
|
197
187
|
Class.new(ActiveRecord::Base) do
|
198
188
|
self.table_name = 'resources'
|
199
189
|
|
200
190
|
belongs_to :organisation
|
201
191
|
|
202
|
-
valhammer
|
192
|
+
valhammer do
|
193
|
+
disable opts
|
194
|
+
end
|
203
195
|
end
|
204
196
|
end
|
205
197
|
|
206
198
|
subject { klass.validators }
|
207
199
|
|
208
|
-
context '
|
209
|
-
let(:
|
200
|
+
context 'disabling an attribute' do
|
201
|
+
let(:disable_opts) { :name }
|
202
|
+
|
203
|
+
it 'excludes all validators for the field' do
|
204
|
+
[:presence, :length, :uniqueness].each do |v|
|
205
|
+
expect(subject).not_to include(a_validator_for(:name, v))
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
context 'disabling a presence validator' do
|
211
|
+
let(:disable_opts) { { name: :presence } }
|
212
|
+
|
213
|
+
it 'excludes the disabled validator' do
|
214
|
+
expect(subject).not_to include(a_validator_for(:name, :presence))
|
215
|
+
end
|
210
216
|
|
211
|
-
it '
|
217
|
+
it 'includes other validators of the same type' do
|
218
|
+
expect(subject).to include(a_validator_for(:mail, :presence))
|
219
|
+
end
|
220
|
+
|
221
|
+
it 'includes other validators for the same field' do
|
212
222
|
expect(subject)
|
213
|
-
.to
|
214
|
-
.and not_include(a_validator_for(:mail, :presence))
|
215
|
-
.and not_include(a_validator_for(:identifier, :presence))
|
216
|
-
.and not_include(a_validator_for(:gpa, :presence))
|
217
|
-
.and not_include(a_validator_for(:organisation, :presence))
|
223
|
+
.to include(a_validator_for(:name, :length, maximum: 100))
|
218
224
|
end
|
219
225
|
end
|
220
226
|
|
221
|
-
context '
|
222
|
-
let(:
|
227
|
+
context 'disabling a presence validator for an association' do
|
228
|
+
let(:disable_opts) { { organisation: :presence } }
|
223
229
|
|
224
|
-
it 'excludes the
|
230
|
+
it 'excludes the disabled validator' do
|
225
231
|
expect(subject)
|
226
|
-
.not_to include(a_validator_for(:
|
232
|
+
.not_to include(a_validator_for(:organisation, :presence))
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
context 'disabling an inclusion validator' do
|
237
|
+
let(:disable_opts) { { injected: :inclusion } }
|
238
|
+
|
239
|
+
it 'excludes the disabled validator' do
|
240
|
+
expect(subject).not_to include(a_validator_for(:injected, :inclusion))
|
227
241
|
end
|
228
242
|
end
|
229
243
|
|
230
|
-
context '
|
231
|
-
let(:
|
244
|
+
context 'disabling a uniqueness validator' do
|
245
|
+
let(:disable_opts) { { identifier: :uniqueness } }
|
232
246
|
|
233
|
-
it 'excludes the
|
247
|
+
it 'excludes the disabled validator' do
|
234
248
|
expect(subject)
|
235
249
|
.not_to include(a_validator_for(:identifier, :uniqueness))
|
236
250
|
end
|
251
|
+
|
252
|
+
it 'includes other validators of the same type' do
|
253
|
+
expect(subject).to include(a_validator_for(:name, :uniqueness))
|
254
|
+
end
|
255
|
+
|
256
|
+
it 'includes other validators for the same field' do
|
257
|
+
expect(subject).to include(a_validator_for(:identifier, :presence))
|
258
|
+
end
|
237
259
|
end
|
238
260
|
|
239
|
-
context '
|
240
|
-
let(:
|
261
|
+
context 'disabling a numericality validator' do
|
262
|
+
let(:disable_opts) { { gpa: :numericality } }
|
263
|
+
|
264
|
+
it 'excludes the disabled validator' do
|
265
|
+
expect(subject).not_to include(a_validator_for(:gpa, :numericality))
|
266
|
+
end
|
267
|
+
|
268
|
+
it 'includes other validators of the same type' do
|
269
|
+
expect(subject).to include(a_validator_for(:age, :numericality))
|
270
|
+
end
|
241
271
|
|
242
|
-
it '
|
243
|
-
expect(subject).to
|
244
|
-
.and not_include(a_validator_for(:gpa, :numericality))
|
272
|
+
it 'includes other validators for the same field' do
|
273
|
+
expect(subject).to include(a_validator_for(:gpa, :presence))
|
245
274
|
end
|
246
275
|
end
|
247
276
|
|
248
|
-
context '
|
249
|
-
let(:
|
277
|
+
context 'disabling a length validator' do
|
278
|
+
let(:disable_opts) { { name: :length } }
|
250
279
|
|
251
|
-
it 'excludes the
|
280
|
+
it 'excludes the disabled validator' do
|
252
281
|
expect(subject).not_to include(a_validator_for(:name, :length))
|
253
282
|
end
|
283
|
+
|
284
|
+
it 'includes other validators of the same type' do
|
285
|
+
expect(subject).to include(a_validator_for(:identifier, :length))
|
286
|
+
end
|
287
|
+
|
288
|
+
it 'includes other validators for the same field' do
|
289
|
+
expect(subject).to include(a_validator_for(:name, :presence))
|
290
|
+
end
|
254
291
|
end
|
255
292
|
end
|
256
293
|
|
data/valhammer.gemspec
CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
21
|
spec.add_dependency 'activerecord', '> 4.1'
|
22
|
+
spec.add_dependency 'activesupport', '> 4.1'
|
22
23
|
|
23
24
|
spec.add_development_dependency 'rails', '> 4.1'
|
24
25
|
spec.add_development_dependency 'bundler'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: valhammer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shaun Mangelsdorf
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-11-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '4.1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activesupport
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4.1'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '4.1'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: rails
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|