database_validations 0.4.0 → 0.5.0

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
  SHA256:
3
- metadata.gz: 0a94ceacef368255d4e55eaf4ac852a839b78238ca47a0d3bceac249e4a1ded3
4
- data.tar.gz: a38b1061a9c345543aa353c5048b2472026c4cb806991c64c5e2b23e48ac6fd7
3
+ metadata.gz: 0540cd1970a66666d9d87489076205155314a0b6e67c105c053fa61f8f22b19a
4
+ data.tar.gz: c8e0a0cac2b2e86571159053e29b840bba391527060adcd501f3f7a4836e0c5e
5
5
  SHA512:
6
- metadata.gz: 3f1543f0a6b04ce50064e74bc56fa059153f7660774932008c5ef50699bb02c31b88f9cee8fa01ef519128932caefe770364536867a5c108ec42fee3e6a31984
7
- data.tar.gz: b0d74dc13be3a54b9bc95c20f5ce24673e5a586392f3d63d3e5f4ad171fadf49bf3b202e4e3e12480af5bf3eba4ed935c9a4cb75a2638248e09c1ae835a634a2
6
+ metadata.gz: b79ba0d354e4337a39d8182de5dca5080980fa97a2b2d4094cba86347f583b7afa2a61b3c1e7440eaacb0f09344b9dd7dbbea553abf8cb64b361a35c79c7c74b
7
+ data.tar.gz: 7a899554d2373b049fc360939ae493dee275648f52d32f243c2c22338e9d643850b6a60749ef524e5bfd8658f47a98209cd87ec3df94f2454650361709221a03
data/README.md CHANGED
@@ -81,8 +81,27 @@ List of supported options from `validates_uniqueness_of` validator:
81
81
 
82
82
  - `scope`: One or more columns by which to limit the scope of the uniqueness constraint.
83
83
  - `message`: Specifies a custom error message (default is: "has already been taken").
84
+ - `if`: Specifies a method or proc to call to determine if the validation should occur
85
+ (e.g. <tt>if: :allow_validation</tt>, or <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>). The method or
86
+ proc should return or evaluate to a `true` or `false` value.
87
+ - `unless`: Specifies a method or proc to call to determine if the validation should not
88
+ occur (e.g. <tt>unless: :skip_validation</tt>, or <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>).
89
+ The method or proc should return or evaluate to a `true` or `false` value.
84
90
 
85
- **Keep in mind**: Even when we don't support `case_sensitive`, `allow_nil` and `allow_blank` options now, the following:
91
+ **Keep in mind**: Both `if` and `unless` options are used only for `valid?` method and provided only for performance reason.
92
+
93
+ ```ruby
94
+ class User < ActiveRecord::Base
95
+ validates_db_uniqueness_of :email, if: -> { email && email_changed? }
96
+ end
97
+
98
+ user = User.create(email: 'email@mail.com', field: 'field')
99
+ user.field = 'another'
100
+
101
+ user.valid? # Will not query the database
102
+ ```
103
+
104
+ **Backward compatibility**: Even when we don't support `case_sensitive`, `allow_nil` and `allow_blank` options now, the following:
86
105
 
87
106
  ```ruby
88
107
  validates_db_uniqueness_of :email
@@ -106,12 +125,6 @@ The list of options to add support:
106
125
  - `case_sensitive`: Looks for an exact match. Ignored by non-text columns (`true` by default).
107
126
  - `allow_nil`: If set to `true`, skips this validation if the attribute is `nil` (default is `false`).
108
127
  - `allow_blank`: If set to `true`, skips this validation if the attribute is blank (default is `false`).
109
- - `if`: Specifies a method, proc or string to call to determine if the validation should occur
110
- (e.g. <tt>if: :allow_validation</tt>, or <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>). The method,
111
- proc or string should return or evaluate to a `true` or `false` value.
112
- - `unless`: Specifies a method, proc or string to call to determine if the validation should not
113
- occur (e.g. <tt>unless: :skip_validation</tt>, or <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>).
114
- The method, proc or string should return or evaluate to a `true` or `false` value.
115
128
 
116
129
  ### Benchmark ([code](https://github.com/toptal/database_validations/blob/master/benchmarks/uniqueness_validator_benchmark.rb))
117
130
 
@@ -1,7 +1,7 @@
1
1
  module DatabaseValidations
2
2
  module Adapters
3
3
  class MysqlAdapter < BaseAdapter
4
- SUPPORTED_OPTIONS = %i[scope message].freeze
4
+ SUPPORTED_OPTIONS = %i[scope message if unless].freeze
5
5
  ADAPTER = :mysql2
6
6
 
7
7
  def error_columns(error_message)
@@ -1,7 +1,7 @@
1
1
  module DatabaseValidations
2
2
  module Adapters
3
3
  class PostgresqlAdapter < BaseAdapter
4
- SUPPORTED_OPTIONS = %i[scope message where].freeze
4
+ SUPPORTED_OPTIONS = %i[scope message where if unless].freeze
5
5
  ADAPTER = :postgresql
6
6
 
7
7
  def error_columns(error_message)
@@ -1,7 +1,7 @@
1
1
  module DatabaseValidations
2
2
  module Adapters
3
3
  class SqliteAdapter < BaseAdapter
4
- SUPPORTED_OPTIONS = %i[scope message].freeze
4
+ SUPPORTED_OPTIONS = %i[scope message if unless].freeze
5
5
  ADAPTER = :sqlite
6
6
 
7
7
  def error_columns(error_message)
@@ -24,6 +24,11 @@ module DatabaseValidations
24
24
  .tap { |opts| opts[:conditions] = -> { where(where_clause_str) } if where_clause }
25
25
  end
26
26
 
27
+ def if_and_unless_pass?(instance)
28
+ (options[:if].nil? || condition_passes?(options[:if], instance)) &&
29
+ (options[:unless].nil? || !condition_passes?(options[:unless], instance))
30
+ end
31
+
27
32
  def key
28
33
  @key ||= Helpers.generate_key(columns)
29
34
  end
@@ -36,6 +41,20 @@ module DatabaseValidations
36
41
  @where_clause ||= options[:where]
37
42
  end
38
43
 
44
+ private
45
+
46
+ attr_reader :adapter, :field, :options
47
+
48
+ def condition_passes?(condition, instance)
49
+ if condition.is_a?(Symbol)
50
+ instance.__send__(condition)
51
+ elsif condition.is_a?(Proc) && condition.arity == 0
52
+ instance.instance_exec(&condition)
53
+ else
54
+ instance.instance_eval(&condition)
55
+ end
56
+ end
57
+
39
58
  def raise_if_unsupported_options!
40
59
  options.except(:attributes).each_key do |option|
41
60
  unless adapter.support_option?(option)
@@ -47,10 +66,6 @@ module DatabaseValidations
47
66
  def raise_if_index_missed!
48
67
  raise Errors::IndexNotFound.new(columns, where_clause, adapter.indexes) unless adapter.find_index(columns, where_clause)
49
68
  end
50
-
51
- private
52
-
53
- attr_reader :adapter, :field, :options
54
69
  end
55
70
  end
56
71
 
@@ -9,7 +9,9 @@ module DatabaseValidations
9
9
  output = super(context)
10
10
 
11
11
  Helpers.each_validator(self.class) do |validator|
12
- validates_with(ActiveRecord::Validations::UniquenessValidator, validator.validates_uniqueness_options)
12
+ if validator.if_and_unless_pass?(self)
13
+ validates_with(ActiveRecord::Validations::UniquenessValidator, validator.validates_uniqueness_options)
14
+ end
13
15
  end
14
16
 
15
17
  errors.empty? && output
@@ -1,3 +1,3 @@
1
1
  module DatabaseValidations
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: database_validations
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evgeniy Demin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-22 00:00:00.000000000 Z
11
+ date: 2018-09-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord