database_validations 0.3.7 → 0.4.0
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/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
|