database_validations 0.5.1 → 0.6.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: 4817334b7a4a7ae57f43e69be04b5969dbb35dcbb39f4bd2ebc52603cf149a15
4
- data.tar.gz: b899b604b2f72021269c39372c60acf0fb4a6805e4d3e2b5f606320aa165bb9a
3
+ metadata.gz: 34f55425dd0da6279bd235d760df174ac1f028365f00d88be653b601207b526d
4
+ data.tar.gz: 8ef9de8f18ba558c5c1cfb9be9af9f0257cd188df35b05545fc479490f799316
5
5
  SHA512:
6
- metadata.gz: d2b50fd0375c72c71ce1a443131a3c16f84118153947a373280ee9b28f6d6572abf3576acbf4be0660e3d436f30abce62d0072c2297c47e557dc894c002ceb74
7
- data.tar.gz: 53e6a6363cc2d64763e9ba3c6089911dc09950c799ffcdbfd51f7d792e48c04f82cb8fc47435b01fad64567ba7ba625c865788ccaf73e79a3745e734f752fed9
6
+ metadata.gz: 8ad092489894f94f52ac4ed99b83dedb383bd0643af8f938c8225c3d1f1cf69d625d2b687346492f45980851a93b45489c76043f5c98be836fcc3739d4f4e1aa
7
+ data.tar.gz: ee668b15d32473eda6b01fc18ab4c9d7336dfd415ee42e33e2e27168f444a3bef7fc4067b6c59793ef5c065cccd5ddca28469439d3c53bb213bc4468e6c42bdb
data/README.md CHANGED
@@ -125,6 +125,8 @@ The list of options to add support:
125
125
  - `allow_nil`: If set to `true`, skips this validation if the attribute is `nil` (default is `false`).
126
126
  - `allow_blank`: If set to `true`, skips this validation if the attribute is blank (default is `false`).
127
127
 
128
+ **Note**: For `PosgreSQL`, it is possible to replace these options with combination of other supported options.
129
+
128
130
  ### Benchmark ([code](https://github.com/toptal/database_validations/blob/master/benchmarks/uniqueness_validator_benchmark.rb))
129
131
 
130
132
  | Case | Validator | SQLite | PostgreSQL | MySQL |
@@ -136,6 +138,26 @@ The list of options to add support:
136
138
  | Each hundredth item is duplicate | validates_db_uniqueness_of | 3.534k (± 5.6%) i/s - 17.748k in 5.039277s | 1.351k (± 6.5%) i/s - 6.750k in 5.017280s | 1.436k (±11.6%) i/s - 7.154k in 5.062644s |
137
139
  | | validates_uniqueness_of | 2.121k (± 6.8%) i/s - 10.653k in 5.049739s | 658.199 (± 6.1%) i/s - 3.350k in 5.110176s | 596.024 (± 6.7%) i/s - 2.989k in 5.041497s |
138
140
 
141
+ ## Testing (RSpec)
142
+
143
+ Add `require database_validations/rspec/matchers'` to your `spec` file.
144
+
145
+ ### validate_db_uniqueness_of
146
+
147
+ Example:
148
+
149
+ ```ruby
150
+ class User < ActiveRecord::Base
151
+ validates_db_uniqueness_of :field, message: 'duplicate', where: '(some_field IS NULL)', scope: :another_field
152
+ end
153
+
154
+ describe 'validations' do
155
+ subject { User }
156
+
157
+ it { is_expected.to validate_db_uniqueness_of(:field).with_message('duplicate').with_where('(some_field IS NULL)').scoped_to(:another_field) }
158
+ end
159
+ ```
160
+
139
161
  ## Development
140
162
 
141
163
  You need to have installed and running `postgresql` and `mysql`.
@@ -1,13 +1,15 @@
1
1
  require 'active_record'
2
2
 
3
3
  require 'database_validations/version'
4
- require 'database_validations/railtie' if defined?(Rails)
5
- require 'database_validations/uniqueness_validator'
6
- require 'database_validations/uniqueness_options'
7
- require 'database_validations/uniqueness_options_storage'
8
- require 'database_validations/errors'
9
- require 'database_validations/helpers'
10
- require 'database_validations/adapters'
4
+
5
+ require 'database_validations/rails/railtie' if defined?(Rails)
6
+
7
+ require 'database_validations/validations/uniqueness_validator'
8
+ require 'database_validations/validations/uniqueness_options'
9
+ require 'database_validations/validations/uniqueness_options_storage'
10
+ require 'database_validations/validations/errors'
11
+ require 'database_validations/validations/helpers'
12
+ require 'database_validations/validations/adapters'
11
13
 
12
14
  module DatabaseValidations
13
15
  extend ActiveSupport::Concern
@@ -3,7 +3,7 @@ require 'active_record/railtie'
3
3
  module DatabaseValidations
4
4
  class Railtie < Rails::Railtie
5
5
  rake_tasks do
6
- load 'tasks/database_validations.rake'
6
+ load 'database_validations/tasks/database_validations.rake'
7
7
 
8
8
  Rake.application.in_namespace(:db) do |namespace|
9
9
  namespace.tasks.each do |task|
@@ -0,0 +1 @@
1
+ require 'database_validations/rspec/uniqueness_validator_matcher'
@@ -0,0 +1,58 @@
1
+ # @scope Models
2
+ #
3
+ # Matches when model validate database uniqueness of some field.
4
+ #
5
+ # Modifiers:
6
+ # * `with_message(message)` -- specifies a message of the error;
7
+ # * `scoped_to(scope)` -- specifies a scope for the validator;
8
+ # * `with_where(where)` -- specifies a where condition for the validator;
9
+ #
10
+ # Example:
11
+ #
12
+ # ```ruby
13
+ # it { expect(Model).to validate_db_uniqueness_of(:field) }
14
+ # ```
15
+ RSpec::Matchers.define :validate_db_uniqueness_of do |field|
16
+ chain(:with_message) do |message|
17
+ @message = message
18
+ end
19
+
20
+ chain(:scoped_to) do |*scope|
21
+ @scope = scope.flatten
22
+ end
23
+
24
+ chain(:with_where) do |where|
25
+ @where = where
26
+ end
27
+
28
+ match do |model|
29
+ @validators = []
30
+
31
+ DatabaseValidations::Helpers.each_validator(model) do |validator|
32
+ @validators << {
33
+ field: validator.field,
34
+ scope: validator.scope,
35
+ where: validator.where_clause,
36
+ message: validator.message
37
+ }
38
+ end
39
+
40
+ @validators.include?(field: field, scope: Array.wrap(@scope), where: @where, message: @message)
41
+ end
42
+
43
+ description do
44
+ desc = "validate database uniqueness of #{field}. "
45
+ desc += "With options - " if @message || @scope || @where
46
+ desc += "message: '#{@message}'; " if @message
47
+ desc += "scope: #{@scope}; " if @scope
48
+ desc += "where: '#{@where}'. " if @where
49
+ desc
50
+ end
51
+
52
+ failure_message do
53
+ <<-TEXT
54
+ There is no such database uniqueness validator.
55
+ Available validators are: #{@validators}.
56
+ TEXT
57
+ end
58
+ end
@@ -0,0 +1,9 @@
1
+ module DatabaseValidations
2
+ module Tasks
3
+ namespace :database_validations do
4
+ task :skip_db_uniqueness_validator_index_check do
5
+ ENV['SKIP_DB_UNIQUENESS_VALIDATOR_INDEX_CHECK'] = 'true'
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,7 +1,7 @@
1
- require 'database_validations/adapters/base_adapter'
2
- require 'database_validations/adapters/sqlite_adapter'
3
- require 'database_validations/adapters/postgresql_adapter'
4
- require 'database_validations/adapters/mysql_adapter'
1
+ require 'database_validations/validations/adapters/base_adapter'
2
+ require 'database_validations/validations/adapters/sqlite_adapter'
3
+ require 'database_validations/validations/adapters/postgresql_adapter'
4
+ require 'database_validations/validations/adapters/mysql_adapter'
5
5
 
6
6
  module DatabaseValidations
7
7
  module Adapters
@@ -27,7 +27,7 @@ module DatabaseValidations
27
27
  end
28
28
 
29
29
  def unify_columns(*columns)
30
- columns.flatten.map(&:to_s).sort
30
+ columns.flatten.compact.map(&:to_s).sort
31
31
  end
32
32
 
33
33
  def generate_key(*columns)
@@ -1,5 +1,7 @@
1
1
  module DatabaseValidations
2
2
  class UniquenessOptions
3
+ attr_reader :field
4
+
3
5
  def initialize(field, options, adapter)
4
6
  @field = field
5
7
  @options = options
@@ -34,16 +36,24 @@ module DatabaseValidations
34
36
  end
35
37
 
36
38
  def columns
37
- @columns ||= Helpers.unify_columns(field, Array.wrap(options[:scope]))
39
+ @columns ||= Helpers.unify_columns(field, scope)
38
40
  end
39
41
 
40
42
  def where_clause
41
43
  @where_clause ||= options[:where]
42
44
  end
43
45
 
46
+ def message
47
+ @message ||= options[:message]
48
+ end
49
+
50
+ def scope
51
+ @scope ||= Array.wrap(options[:scope])
52
+ end
53
+
44
54
  private
45
55
 
46
- attr_reader :adapter, :field, :options
56
+ attr_reader :adapter, :options
47
57
 
48
58
  def condition_passes?(condition, instance)
49
59
  if condition.is_a?(Symbol)
@@ -1,3 +1,3 @@
1
1
  module DatabaseValidations
2
- VERSION = "0.5.1"
2
+ VERSION = '0.6.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.5.1
4
+ version: 0.6.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-25 00:00:00.000000000 Z
11
+ date: 2018-09-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -128,6 +128,20 @@ dependencies:
128
128
  - - "~>"
129
129
  - !ruby/object:Gem::Version
130
130
  version: '3.0'
131
+ - !ruby/object:Gem::Dependency
132
+ name: climate_control
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: '0.2'
138
+ type: :development
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - "~>"
143
+ - !ruby/object:Gem::Version
144
+ version: '0.2'
131
145
  description: |-
132
146
  ActiveRecord provides validations on app level but it won't guarantee the
133
147
  consistent. In some cases, like `validates_uniqueness_of` it executes
@@ -144,19 +158,21 @@ files:
144
158
  - LICENSE.txt
145
159
  - README.md
146
160
  - lib/database_validations.rb
147
- - lib/database_validations/adapters.rb
148
- - lib/database_validations/adapters/base_adapter.rb
149
- - lib/database_validations/adapters/mysql_adapter.rb
150
- - lib/database_validations/adapters/postgresql_adapter.rb
151
- - lib/database_validations/adapters/sqlite_adapter.rb
152
- - lib/database_validations/errors.rb
153
- - lib/database_validations/helpers.rb
154
- - lib/database_validations/railtie.rb
155
- - lib/database_validations/uniqueness_options.rb
156
- - lib/database_validations/uniqueness_options_storage.rb
157
- - lib/database_validations/uniqueness_validator.rb
161
+ - lib/database_validations/rails/railtie.rb
162
+ - lib/database_validations/rspec/matchers.rb
163
+ - lib/database_validations/rspec/uniqueness_validator_matcher.rb
164
+ - lib/database_validations/tasks/database_validations.rake
165
+ - lib/database_validations/validations/adapters.rb
166
+ - lib/database_validations/validations/adapters/base_adapter.rb
167
+ - lib/database_validations/validations/adapters/mysql_adapter.rb
168
+ - lib/database_validations/validations/adapters/postgresql_adapter.rb
169
+ - lib/database_validations/validations/adapters/sqlite_adapter.rb
170
+ - lib/database_validations/validations/errors.rb
171
+ - lib/database_validations/validations/helpers.rb
172
+ - lib/database_validations/validations/uniqueness_options.rb
173
+ - lib/database_validations/validations/uniqueness_options_storage.rb
174
+ - lib/database_validations/validations/uniqueness_validator.rb
158
175
  - lib/database_validations/version.rb
159
- - lib/tasks/database_validations.rake
160
176
  homepage: https://github.com/toptal/database_validations
161
177
  licenses:
162
178
  - MIT
@@ -1,5 +0,0 @@
1
- namespace :database_validations do
2
- task :skip_db_uniqueness_validator_index_check do
3
- ENV['SKIP_DB_UNIQUENESS_VALIDATOR_INDEX_CHECK'] = 'true'
4
- end
5
- end