valhammer 0.2.2 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f5cc152c6e61d42ceb78240e85b5c864341736ad
4
- data.tar.gz: 1eb227b60d2c901dbb84105774725419574a7167
3
+ metadata.gz: 758eec1c687a507398055fdb46d849004962b1b6
4
+ data.tar.gz: bda97ef82eb60f40da4789514710c122897a35ab
5
5
  SHA512:
6
- metadata.gz: f285efa488450a71180ea6c9065c79c120a1c005a51a7c3640e9566c79ad10428d76b1af4e88fb58d3a1b64b9f5fdf88168a7c4dcdff3f0c47c2fb854aa01772
7
- data.tar.gz: b495dc9987aa836118f8eb062a0c2d7ed3079be5640c5e372520af8e99aab2225fe5adc2231b92133b54aa4be115dd377033975f60c148c1dbf9d859f0883a55
6
+ metadata.gz: 6a8dc0e51c7b2ebb78fc0a6536be61a49a7b66257807f6dd901e28736631b755c7fdebd4639d350780862af0f8de2fce2846b7a1e55566b435aaee018e1c83a7
7
+ data.tar.gz: af035d6d7dab4931dbbabe1fa1602b30fd98610e90b2ec46f8a631749b4ae734caf1774afec8f7f57f495602a6c68a1a534ca7d7aa5466713303630c06a42c89
data/.simplecov CHANGED
@@ -1,6 +1,4 @@
1
- require 'codeclimate-test-reporter'
2
- CodeClimate::TestReporter.start
3
-
1
+ SimpleCov.command_name 'rspec'
4
2
  SimpleCov.start do
5
3
  add_filter('spec')
6
4
  end
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
- To disable a kind of validation, pass an option to the `valhammer` method:
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 uniqueness: false
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
- VALHAMMER_DEFAULT_OPTS = { presence: true, uniqueness: true,
4
- numericality: true, length: true,
5
- inclusion: true }.freeze
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 :VALHAMMER_DEFAULT_OPTS, :VALHAMMER_EXCLUDED_FIELDS
32
+ private_constant :VALHAMMER_EXCLUDED_FIELDS, :DisabledFieldConfig
10
33
 
11
- def valhammer(opts = {})
34
+ def valhammer(&bl)
12
35
  @valhammer_indexes = connection.indexes(table_name)
13
- opts = VALHAMMER_DEFAULT_OPTS.merge(opts)
36
+ config = DisabledFieldConfig.perform(&bl)
37
+
14
38
  columns_hash.each do |name, column|
15
- valhammer_validate(name, column, opts)
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, opts)
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.nil?
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 unless opts[:numericality]
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
 
@@ -1,3 +1,3 @@
1
1
  module Valhammer
2
- VERSION = '0.2.2'.freeze
2
+ VERSION = '0.3.1'.freeze
3
3
  end
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 'with disabled validations' do
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 = { disabled_validator => false }
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(opts)
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 ':presence' do
209
- let(:disabled_validator) { :presence }
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 'excludes the presence validator' do
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 not_include(a_validator_for(:name, :presence))
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 ':inclusion' do
222
- let(:disabled_validator) { :inclusion }
227
+ context 'disabling a presence validator for an association' do
228
+ let(:disable_opts) { { organisation: :presence } }
223
229
 
224
- it 'excludes the inclusion validator' do
230
+ it 'excludes the disabled validator' do
225
231
  expect(subject)
226
- .not_to include(a_validator_for(:injected, :inclusion))
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 ':uniqueness' do
231
- let(:disabled_validator) { :uniqueness }
244
+ context 'disabling a uniqueness validator' do
245
+ let(:disable_opts) { { identifier: :uniqueness } }
232
246
 
233
- it 'excludes the uniqueness validator' do
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 ':numericality' do
240
- let(:disabled_validator) { :numericality }
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 'excludes the numericality validator' do
243
- expect(subject).to not_include(a_validator_for(:age, :numericality))
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 ':length' do
249
- let(:disabled_validator) { :length }
277
+ context 'disabling a length validator' do
278
+ let(:disable_opts) { { name: :length } }
250
279
 
251
- it 'excludes the length validator' do
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.2.2
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-06-13 00:00:00.000000000 Z
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