database_validations 0.1.0 → 0.3.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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +53 -41
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 290f698bb3acea997e8154fce04fc2bc193ad979ed13a26ba3b06cada78a0832
4
- data.tar.gz: 202646e73ce8cac4fd33af5c52ef295d710cd18707ea8572903f6f4c50846fdf
3
+ metadata.gz: 75cc8e49376be81dd56be2da6de60dd9e4763243af4aef1ecb3bc5d5324bfabc
4
+ data.tar.gz: 7d091827be83bcfa46e89bdbaa7ff5a1964c063272a3b3099b1169e678d5d1b0
5
5
  SHA512:
6
- metadata.gz: 38d5853ee7d94b95c72e60e548aeefa7d08b0f75598641ac64451a5197eb1a8d2a4111be1ede94e7cdbfac9a23096ac9f23ecd1a50801f7604c5692b8c95858a
7
- data.tar.gz: ebd84880d6ac224f7a82e184ad9368b02f143ceb9d807e32d973922a80fa60e3575bee9b162faec335a21680d4ec17cde34de99ca7ac994da807aca7df53e388
6
+ metadata.gz: c60c9a3eb7ea1783235b4636d7c9baa0af690a2218593ba96853e6f18647a01feb0449676c920d9afb6e73145d3d44df0ce1f02f153c4a161a22983204823102
7
+ data.tar.gz: 478bcddd2b83c208b34632bf782ba27e9c948c878fb7c6d751f65fb08c6ac206f1d3a7c6b28706299499f592e827dd6b8381a306014e03dd8200776ccb24ec60
data/README.md CHANGED
@@ -27,6 +27,35 @@ Or install it yourself as:
27
27
 
28
28
  Supported databases: `postgresql`, `mysql` and `sqlite`.
29
29
 
30
+ ### Pros and Cons
31
+
32
+ Advantages:
33
+ - Provides true uniqueness on the database level because it handles race conditions cases properly.
34
+ - Check the existence of correct unique index at the boot time.
35
+ - It's faster. See [Benchmark](https://github.com/toptal/database_validations#benchmark-code) section for details.
36
+
37
+ Disadvantages:
38
+ - Cannot handle multiple validations at once because database raises only one error for all indexes per query.
39
+ ```ruby
40
+ class User < ActiveRecord::Base
41
+ validates_db_uniqueness_of :email
42
+ validates_db_uniqueness_of :name
43
+ end
44
+
45
+ original = User.create(name: 'name', email: 'email@mail.com')
46
+ dupe = User.create(name: 'name', email: 'email@mail.com')
47
+ # => false
48
+ dupe.errors.messages
49
+ # => {:name=>["has already been taken"]}
50
+ ```
51
+
52
+ ### How it works?
53
+
54
+ We override `save` and `save!` methods where we rescue `ActiveRecord::RecordNotUnique` and add proper errors
55
+ for compatibility.
56
+
57
+ For `valid?` we use implementation from `validates_uniqueness_of` where we query the database.
58
+
30
59
  ### Usage
31
60
 
32
61
  ```ruby
@@ -43,26 +72,29 @@ User.create!(email: 'email@mail.com')
43
72
  # => ActiveRecord::RecordInvalid Validation failed: email has already been taken
44
73
  ```
45
74
 
46
- **Note**: keep in mind, we don't check uniqueness validity through `valid?` method.
47
- ```ruby
48
- original = User.create(email: 'email@mail.com')
49
- dupe = User.new(email: 'email@mail.com')
50
- dupe.valid?
51
- # => true
52
- dupe.save
53
- # => false
54
- dupe.errors.messages
55
- # => {:email=>["has already been taken"]}
56
- ```
57
-
58
75
  ### Configuration options
59
76
 
60
77
  We want to provide full compatibility with existing `validates_uniqueness_of` validator.
61
78
 
62
- This list of options are from `validates_uniqueness_of` validator:
79
+ This list of supported options from `validates_uniqueness_of` validator:
63
80
 
64
81
  - `scope`: One or more columns by which to limit the scope of the uniqueness constraint.
65
82
  - `message`: Specifies a custom error message (default is: "has already been taken").
83
+
84
+ **Keep in mind**: Even when we don't support `case_sensitive`, `allow_nil` and `allow_blank` options now, the following:
85
+
86
+ ```ruby
87
+ validates_db_uniqueness_of :email
88
+ ```
89
+
90
+ Is the same by default as following
91
+
92
+ ```ruby
93
+ validates_uniqueness_of :email, allow_nil: true, allow_blank: false, case_sensitive: true
94
+ ```
95
+
96
+ The list of options to add support:
97
+
66
98
  - `conditions`: Specify the conditions to be included as a <tt>WHERE</tt> SQL fragment to
67
99
  limit the uniqueness constraint lookup (e.g. <tt>conditions: -> { where(status: 'active') }</tt>).
68
100
  - `case_sensitive`: Looks for an exact match. Ignored by non-text columns (`true` by default).
@@ -75,36 +107,16 @@ proc or string should return or evaluate to a `true` or `false` value.
75
107
  occur (e.g. <tt>unless: :skip_validation</tt>, or <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>).
76
108
  The method, proc or string should return or evaluate to a `true` or `false` value.
77
109
 
78
- **Note**: only few options are supported now: `scope`.
79
-
80
110
  ### Benchmark ([code](https://github.com/toptal/database_validations/blob/master/benchmarks/uniqueness_validator_benchmark.rb))
81
111
 
82
- #### Saving only duplicates items ([code](https://github.com/toptal/database_validations/blob/master/benchmarks/uniqueness_validator_benchmark.rb#L56))
83
-
84
- ```
85
- validates_db_uniqueness_of
86
- 1.487k10.1%) i/s - 7.425k in 5.053608s
87
- validates_uniqueness_of
88
- 1.500k18.3%) i/s - 7.238k in 5.024355s
89
- ```
90
-
91
- #### Saving only unique items ([code](https://github.com/toptal/database_validations/blob/master/benchmarks/uniqueness_validator_benchmark.rb#L63))
92
-
93
- ```
94
- validates_db_uniqueness_of
95
- 3.558k (± 3.5%) i/s - 18.105k in 5.094799s
96
- validates_uniqueness_of
97
- 2.031k (± 8.3%) i/s - 10.241k in 5.080059s
98
- ```
99
-
100
- #### Each hundredth item is duplicate ([code](https://github.com/toptal/database_validations/blob/master/benchmarks/uniqueness_validator_benchmark.rb#L70))
101
-
102
- ```
103
- validates_db_uniqueness_of
104
- 3.499k (± 4.8%) i/s - 17.628k in 5.050887s
105
- validates_uniqueness_of
106
- 2.074k (± 8.6%) i/s - 10.388k in 5.063879s
107
- ```
112
+ | Case | Validator | SQLite | PostgreSQL | MySQL |
113
+ | -------------------------------- | -------------------------- | ------------------------------------------ | ------------------------------------------ | ------------------------------------------ |
114
+ | Save duplicate item only | validates_db_uniqueness_of | 1.404k (±14.7%) i/s - 6.912k in 5.043409s | 508.889 (± 2.8%) i/s - 2.550k in 5.015044s | 649.356 (±11.5%) i/s - 3.283k in 5.153444s |
115
+ | | validates_uniqueness_of | 1.505k (±14.6%) i/s - 7.448k in 5.075696s | 637.017 (±14.1%) i/s - 3.128k in 5.043434s | 473.561 (± 9.7%) i/s - 2.352k in 5.021151s |
116
+ | Save unique item only | validates_db_uniqueness_of | 3.241k18.3%) i/s - 15.375k in 5.014244s | 1.345k (± 5.5%) i/s - 6.834k in 5.096706s | 1.439k (±12.9%) i/s - 7.100k in 5.033603s |
117
+ | | validates_uniqueness_of | 2.002k (±10.9%) i/s - 9.900k in 5.018449s | 667.100 (± 4.8%) i/s - 3.350k in 5.034451s | 606.334 (± 4.9%) i/s - 3.068k in 5.072587s |
118
+ | 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 |
119
+ | | 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 |
108
120
 
109
121
  ## Development
110
122
 
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.1.0
4
+ version: 0.3.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-08-28 00:00:00.000000000 Z
11
+ date: 2018-08-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord