database_validations 0.3.7 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +9 -4
- data/lib/database_validations/adapters/base_adapter.rb +2 -2
- data/lib/database_validations/adapters/postgresql_adapter.rb +1 -1
- data/lib/database_validations/errors.rb +11 -3
- data/lib/database_validations/helpers.rb +0 -1
- data/lib/database_validations/uniqueness_options.rb +11 -3
- data/lib/database_validations/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a94ceacef368255d4e55eaf4ac852a839b78238ca47a0d3bceac249e4a1ded3
|
4
|
+
data.tar.gz: a38b1061a9c345543aa353c5048b2472026c4cb806991c64c5e2b23e48ac6fd7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f1543f0a6b04ce50064e74bc56fa059153f7660774932008c5ef50699bb02c31b88f9cee8fa01ef519128932caefe770364536867a5c108ec42fee3e6a31984
|
7
|
+
data.tar.gz: b0d74dc13be3a54b9bc95c20f5ce24673e5a586392f3d63d3e5f4ad171fadf49bf3b202e4e3e12480af5bf3eba4ed935c9a4cb75a2638248e09c1ae835a634a2
|
data/README.md
CHANGED
@@ -77,7 +77,7 @@ User.create!(email: 'email@mail.com')
|
|
77
77
|
|
78
78
|
We want to provide full compatibility with existing `validates_uniqueness_of` validator.
|
79
79
|
|
80
|
-
|
80
|
+
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").
|
@@ -88,16 +88,21 @@ This list of supported options from `validates_uniqueness_of` validator:
|
|
88
88
|
validates_db_uniqueness_of :email
|
89
89
|
```
|
90
90
|
|
91
|
-
Is the same by default as following
|
91
|
+
Is the same by default as the following
|
92
92
|
|
93
93
|
```ruby
|
94
94
|
validates_uniqueness_of :email, allow_nil: true, allow_blank: false, case_sensitive: true
|
95
95
|
```
|
96
96
|
|
97
|
+
List of supported options for `PostgreSQL` only:
|
98
|
+
|
99
|
+
- `where`: Specify the conditions to be included as a <tt>WHERE</tt> SQL fragment to
|
100
|
+
limit the uniqueness constraint lookup (e.g. <tt>where: "(status = 'active')"</tt>).
|
101
|
+
For backward compatibility, this will be converted automatically
|
102
|
+
to <tt>conditions: -> { where("(status = 'active')") }</tt> for `valid?` method.
|
103
|
+
|
97
104
|
The list of options to add support:
|
98
105
|
|
99
|
-
- `conditions`: Specify the conditions to be included as a <tt>WHERE</tt> SQL fragment to
|
100
|
-
limit the uniqueness constraint lookup (e.g. <tt>conditions: -> { where(status: 'active') }</tt>).
|
101
106
|
- `case_sensitive`: Looks for an exact match. Ignored by non-text columns (`true` by default).
|
102
107
|
- `allow_nil`: If set to `true`, skips this validation if the attribute is `nil` (default is `false`).
|
103
108
|
- `allow_blank`: If set to `true`, skips this validation if the attribute is blank (default is `false`).
|
@@ -12,8 +12,8 @@ module DatabaseValidations
|
|
12
12
|
indexes.find { |index| index.name == index_name }
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
16
|
-
indexes.find { |index| index.columns.map(&:to_s).sort ==
|
15
|
+
def find_index(columns, where)
|
16
|
+
indexes.find { |index| index.columns.map(&:to_s).sort == columns && index.where == where }
|
17
17
|
end
|
18
18
|
|
19
19
|
def indexes
|
@@ -3,14 +3,22 @@ module DatabaseValidations
|
|
3
3
|
class Base < StandardError; end
|
4
4
|
|
5
5
|
class IndexNotFound < Base
|
6
|
-
attr_reader :columns
|
6
|
+
attr_reader :columns, :where_clause, :available_indexes
|
7
7
|
|
8
|
-
def initialize(columns)
|
8
|
+
def initialize(columns, where_clause, available_indexes)
|
9
9
|
@columns = columns.map(&:to_s)
|
10
|
-
|
10
|
+
@where_clause = where_clause
|
11
|
+
@available_indexes = available_indexes
|
12
|
+
|
13
|
+
super "No unique index found with #{columns_and_where_text(columns, where_clause)}. "\
|
14
|
+
"Available indexes are: [#{self.available_indexes.map { |ind| columns_and_where_text(ind.columns, ind.where) }.join(', ')}]. "\
|
11
15
|
"Use ENV['SKIP_DB_UNIQUENESS_VALIDATOR_INDEX_CHECK']=true in case you want to skip the check. "\
|
12
16
|
"For example, when you run migrations."
|
13
17
|
end
|
18
|
+
|
19
|
+
def columns_and_where_text(columns, where)
|
20
|
+
"columns: #{columns}#{" and where: #{where}" if where}"
|
21
|
+
end
|
14
22
|
end
|
15
23
|
|
16
24
|
class UnknownDatabase < Base
|
@@ -6,7 +6,6 @@ module DatabaseValidations
|
|
6
6
|
key = generate_key(Adapters.factory(instance.class).error_columns(error.message))
|
7
7
|
|
8
8
|
each_options_storage(instance.class) do |storage|
|
9
|
-
# storage has this then return
|
10
9
|
return storage[key].handle_unique_error(instance) if storage[key]
|
11
10
|
end
|
12
11
|
|
@@ -10,14 +10,18 @@ module DatabaseValidations
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def handle_unique_error(instance)
|
13
|
-
error_options = options.except(:case_sensitive, :scope, :conditions, :attributes)
|
13
|
+
error_options = options.except(:case_sensitive, :scope, :conditions, :attributes, :where)
|
14
14
|
error_options[:value] = instance.public_send(options[:attributes])
|
15
15
|
|
16
16
|
instance.errors.add(options[:attributes], :taken, error_options)
|
17
17
|
end
|
18
18
|
|
19
19
|
def validates_uniqueness_options
|
20
|
-
|
20
|
+
where_clause_str = where_clause
|
21
|
+
|
22
|
+
options.except(:where)
|
23
|
+
.merge(allow_nil: true, case_sensitive: true, allow_blank: false)
|
24
|
+
.tap { |opts| opts[:conditions] = -> { where(where_clause_str) } if where_clause }
|
21
25
|
end
|
22
26
|
|
23
27
|
def key
|
@@ -28,6 +32,10 @@ module DatabaseValidations
|
|
28
32
|
@columns ||= Helpers.unify_columns(field, Array.wrap(options[:scope]))
|
29
33
|
end
|
30
34
|
|
35
|
+
def where_clause
|
36
|
+
@where_clause ||= options[:where]
|
37
|
+
end
|
38
|
+
|
31
39
|
def raise_if_unsupported_options!
|
32
40
|
options.except(:attributes).each_key do |option|
|
33
41
|
unless adapter.support_option?(option)
|
@@ -37,7 +45,7 @@ module DatabaseValidations
|
|
37
45
|
end
|
38
46
|
|
39
47
|
def raise_if_index_missed!
|
40
|
-
raise Errors::IndexNotFound.new(columns) unless adapter.
|
48
|
+
raise Errors::IndexNotFound.new(columns, where_clause, adapter.indexes) unless adapter.find_index(columns, where_clause)
|
41
49
|
end
|
42
50
|
|
43
51
|
private
|