database_validations 0.1.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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