rescue_unique_constraint-p 2.0.0 → 2.1.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/.gitignore +11 -23
- data/.rubocop.yml +18 -1
- data/.ruby-gemset +1 -1
- data/.ruby-version +1 -1
- data/Gemfile +10 -0
- data/Gemfile.lock +123 -0
- data/README.md +2 -2
- data/Rakefile +4 -2
- data/lib/rescue_unique_constraint-p/adapter/mysql_adapter.rb +2 -0
- data/lib/rescue_unique_constraint-p/adapter/postgresql_adapter.rb +2 -0
- data/lib/rescue_unique_constraint-p/adapter/sqlite_adapter.rb +3 -1
- data/lib/rescue_unique_constraint-p/index.rb +3 -0
- data/lib/rescue_unique_constraint-p/rescue_handler.rb +5 -2
- data/lib/rescue_unique_constraint-p/version.rb +1 -1
- data/lib/rescue_unique_constraint-p.rb +3 -1
- data/rescue_unique_constraint.gemspec +22 -0
- data/spec/fake_app/thing.rb +8 -0
- data/spec/rescue_unique_constraint-p_spec.rb +42 -0
- data/spec/spec_helper.rb +38 -0
- metadata +16 -132
- data/Makefile +0 -3
- data/rescue_unique_constraint-p.gemspec +0 -30
- data/spec/rescue_unique_constraint_spec-p.rb +0 -58
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5ebdc760b9c5b155ceb723b04e8204c86e9e4a3964b7a6fa567da57201b01e14
|
|
4
|
+
data.tar.gz: e443559cae4ae3a758868d56e87550b0bdd6906db8142d273138f5073aee7031
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c87ba2827e3f6e3d40b5140ced66bf192c8b2a10b423d8f0c10ec520a6483a2027fec17d29c33d003b5cf1cc46ed6032d0d2d9f8867b8143bc033c7d46356478
|
|
7
|
+
data.tar.gz: 56c712163196c0fffcda5b67581531df7942a55f6a956c09bd83a028f8de79bc31e662a662c76b57b814cb2e789fd780ce4e36022af1b96a27d7bd1cb4e59ad2
|
data/.gitignore
CHANGED
|
@@ -1,23 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
lib/bundler/man
|
|
13
|
-
pkg
|
|
14
|
-
rdoc
|
|
15
|
-
spec/reports
|
|
16
|
-
test/tmp
|
|
17
|
-
test/version_tmp
|
|
18
|
-
tmp
|
|
19
|
-
*.bundle
|
|
20
|
-
*.so
|
|
21
|
-
*.o
|
|
22
|
-
*.a
|
|
23
|
-
mkmf.log
|
|
1
|
+
/.bundle/
|
|
2
|
+
/.yardoc
|
|
3
|
+
/_yardoc/
|
|
4
|
+
/coverage/
|
|
5
|
+
/doc/
|
|
6
|
+
/pkg/
|
|
7
|
+
/spec/reports/
|
|
8
|
+
/tmp/
|
|
9
|
+
|
|
10
|
+
# rspec failure tracking
|
|
11
|
+
.rspec_status
|
data/.rubocop.yml
CHANGED
|
@@ -1,2 +1,19 @@
|
|
|
1
|
+
require:
|
|
2
|
+
- rubocop-rake
|
|
3
|
+
- rubocop-rspec
|
|
4
|
+
|
|
1
5
|
AllCops:
|
|
2
|
-
|
|
6
|
+
NewCops: enable
|
|
7
|
+
TargetRubyVersion: 2.6
|
|
8
|
+
|
|
9
|
+
Layout/LineLength:
|
|
10
|
+
Max: 150
|
|
11
|
+
|
|
12
|
+
Metrics/BlockLength:
|
|
13
|
+
Enabled: false
|
|
14
|
+
|
|
15
|
+
Metrics/MethodLength:
|
|
16
|
+
Max: 15
|
|
17
|
+
|
|
18
|
+
Style/Documentation:
|
|
19
|
+
Enabled: false
|
data/.ruby-gemset
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
rescue_unique_constraint
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.1
|
|
1
|
+
3.4.1
|
data/Gemfile
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
source 'https://rubygems.org'
|
|
2
4
|
|
|
3
5
|
# Specify your gem's dependencies in rescue_unique_constraint.gemspec
|
|
4
6
|
gemspec
|
|
7
|
+
|
|
8
|
+
gem 'activerecord', '>= 3.2', '< 8'
|
|
9
|
+
gem 'jazz_fingers'
|
|
10
|
+
gem 'rake'
|
|
11
|
+
gem 'rspec'
|
|
12
|
+
gem 'rubocop-rake'
|
|
13
|
+
gem 'rubocop-rspec'
|
|
14
|
+
gem 'sqlite3'
|
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
rescue_unique_constraint-p (2.1.0)
|
|
5
|
+
|
|
6
|
+
GEM
|
|
7
|
+
remote: https://rubygems.org/
|
|
8
|
+
specs:
|
|
9
|
+
activemodel (7.2.2.1)
|
|
10
|
+
activesupport (= 7.2.2.1)
|
|
11
|
+
activerecord (7.2.2.1)
|
|
12
|
+
activemodel (= 7.2.2.1)
|
|
13
|
+
activesupport (= 7.2.2.1)
|
|
14
|
+
timeout (>= 0.4.0)
|
|
15
|
+
activesupport (7.2.2.1)
|
|
16
|
+
base64
|
|
17
|
+
benchmark (>= 0.3)
|
|
18
|
+
bigdecimal
|
|
19
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
|
20
|
+
connection_pool (>= 2.2.5)
|
|
21
|
+
drb
|
|
22
|
+
i18n (>= 1.6, < 2)
|
|
23
|
+
logger (>= 1.4.2)
|
|
24
|
+
minitest (>= 5.1)
|
|
25
|
+
securerandom (>= 0.3)
|
|
26
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
|
27
|
+
amazing_print (1.7.2)
|
|
28
|
+
ast (2.4.2)
|
|
29
|
+
base64 (0.2.0)
|
|
30
|
+
benchmark (0.4.0)
|
|
31
|
+
bigdecimal (3.1.9)
|
|
32
|
+
byebug (11.1.3)
|
|
33
|
+
coderay (1.1.3)
|
|
34
|
+
concurrent-ruby (1.3.5)
|
|
35
|
+
connection_pool (2.5.0)
|
|
36
|
+
coolline (0.5.0)
|
|
37
|
+
unicode_utils (~> 1.4)
|
|
38
|
+
diff-lcs (1.5.0)
|
|
39
|
+
drb (2.2.1)
|
|
40
|
+
i18n (1.14.7)
|
|
41
|
+
concurrent-ruby (~> 1.0)
|
|
42
|
+
jazz_fingers (6.2.0)
|
|
43
|
+
amazing_print (~> 1.3)
|
|
44
|
+
pry (~> 0.10)
|
|
45
|
+
pry-byebug (~> 3.9)
|
|
46
|
+
pry-coolline (~> 0.2)
|
|
47
|
+
json (2.9.1)
|
|
48
|
+
language_server-protocol (3.17.0.4)
|
|
49
|
+
logger (1.6.5)
|
|
50
|
+
method_source (1.1.0)
|
|
51
|
+
minitest (5.25.4)
|
|
52
|
+
parallel (1.26.3)
|
|
53
|
+
parser (3.3.7.1)
|
|
54
|
+
ast (~> 2.4.1)
|
|
55
|
+
racc
|
|
56
|
+
pry (0.14.2)
|
|
57
|
+
coderay (~> 1.1)
|
|
58
|
+
method_source (~> 1.0)
|
|
59
|
+
pry-byebug (3.10.1)
|
|
60
|
+
byebug (~> 11.0)
|
|
61
|
+
pry (>= 0.13, < 0.15)
|
|
62
|
+
pry-coolline (0.2.6)
|
|
63
|
+
coolline (~> 0.5)
|
|
64
|
+
pry (~> 0.13)
|
|
65
|
+
racc (1.8.1)
|
|
66
|
+
rainbow (3.1.1)
|
|
67
|
+
rake (10.5.0)
|
|
68
|
+
regexp_parser (2.10.0)
|
|
69
|
+
rspec (3.11.0)
|
|
70
|
+
rspec-core (~> 3.11.0)
|
|
71
|
+
rspec-expectations (~> 3.11.0)
|
|
72
|
+
rspec-mocks (~> 3.11.0)
|
|
73
|
+
rspec-core (3.11.0)
|
|
74
|
+
rspec-support (~> 3.11.0)
|
|
75
|
+
rspec-expectations (3.11.0)
|
|
76
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
77
|
+
rspec-support (~> 3.11.0)
|
|
78
|
+
rspec-mocks (3.11.1)
|
|
79
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
80
|
+
rspec-support (~> 3.11.0)
|
|
81
|
+
rspec-support (3.11.0)
|
|
82
|
+
rubocop (1.71.2)
|
|
83
|
+
json (~> 2.3)
|
|
84
|
+
language_server-protocol (>= 3.17.0)
|
|
85
|
+
parallel (~> 1.10)
|
|
86
|
+
parser (>= 3.3.0.2)
|
|
87
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
88
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
|
89
|
+
rubocop-ast (>= 1.38.0, < 2.0)
|
|
90
|
+
ruby-progressbar (~> 1.7)
|
|
91
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
|
92
|
+
rubocop-ast (1.38.0)
|
|
93
|
+
parser (>= 3.3.1.0)
|
|
94
|
+
rubocop-rake (0.6.0)
|
|
95
|
+
rubocop (~> 1.0)
|
|
96
|
+
rubocop-rspec (3.4.0)
|
|
97
|
+
rubocop (~> 1.61)
|
|
98
|
+
ruby-progressbar (1.13.0)
|
|
99
|
+
securerandom (0.4.1)
|
|
100
|
+
sqlite3 (1.4.2)
|
|
101
|
+
timeout (0.4.3)
|
|
102
|
+
tzinfo (2.0.6)
|
|
103
|
+
concurrent-ruby (~> 1.0)
|
|
104
|
+
unicode-display_width (3.1.4)
|
|
105
|
+
unicode-emoji (~> 4.0, >= 4.0.4)
|
|
106
|
+
unicode-emoji (4.0.4)
|
|
107
|
+
unicode_utils (1.4.0)
|
|
108
|
+
|
|
109
|
+
PLATFORMS
|
|
110
|
+
x86_64-darwin-21
|
|
111
|
+
|
|
112
|
+
DEPENDENCIES
|
|
113
|
+
activerecord (>= 3.2, < 8)
|
|
114
|
+
jazz_fingers
|
|
115
|
+
rake
|
|
116
|
+
rescue_unique_constraint-p!
|
|
117
|
+
rspec
|
|
118
|
+
rubocop-rake
|
|
119
|
+
rubocop-rspec
|
|
120
|
+
sqlite3
|
|
121
|
+
|
|
122
|
+
BUNDLED WITH
|
|
123
|
+
2.3.7
|
data/README.md
CHANGED
|
@@ -16,7 +16,7 @@ See Usage for more info.
|
|
|
16
16
|
|
|
17
17
|
Add this line to your application's Gemfile:
|
|
18
18
|
|
|
19
|
-
gem 'rescue_unique_constraint'
|
|
19
|
+
gem 'rescue_unique_constraint-p'
|
|
20
20
|
|
|
21
21
|
And then execute:
|
|
22
22
|
|
|
@@ -24,7 +24,7 @@ And then execute:
|
|
|
24
24
|
|
|
25
25
|
Or install it yourself as:
|
|
26
26
|
|
|
27
|
-
$ gem install rescue_unique_constraint
|
|
27
|
+
$ gem install rescue_unique_constraint-p
|
|
28
28
|
|
|
29
29
|
## Usage
|
|
30
30
|
|
data/Rakefile
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module RescueUniqueConstraint
|
|
2
4
|
module Adapter
|
|
3
5
|
class SqliteAdapter
|
|
@@ -11,7 +13,7 @@ module RescueUniqueConstraint
|
|
|
11
13
|
# Step1: extract column names from above message on which unique constraint failed.
|
|
12
14
|
# Step2: Check if this index's field is among those columns.
|
|
13
15
|
def index_error?(index, error_message)
|
|
14
|
-
column_names = error_message.scan(
|
|
16
|
+
column_names = error_message.scan(/(?<=#{@table_name}\.)\w+/)
|
|
15
17
|
column_names.include?(index.field)
|
|
16
18
|
end
|
|
17
19
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module RescueUniqueConstraint
|
|
2
4
|
# Handles storing and matching [index, field] pairs to exceptions
|
|
3
5
|
class RescueHandler
|
|
@@ -14,7 +16,9 @@ module RescueUniqueConstraint
|
|
|
14
16
|
indexes = indexes_to_rescue_on.select do |index|
|
|
15
17
|
database_adapter.index_error?(index, e.message)
|
|
16
18
|
end
|
|
19
|
+
|
|
17
20
|
raise e unless indexes.any?
|
|
21
|
+
|
|
18
22
|
indexes
|
|
19
23
|
end
|
|
20
24
|
|
|
@@ -23,7 +27,7 @@ module RescueUniqueConstraint
|
|
|
23
27
|
attr_reader :indexes_to_rescue_on, :model
|
|
24
28
|
|
|
25
29
|
def database_adapter
|
|
26
|
-
@
|
|
30
|
+
@database_adapter ||=
|
|
27
31
|
case database_name
|
|
28
32
|
when :mysql2
|
|
29
33
|
Adapter::MysqlAdapter.new
|
|
@@ -34,7 +38,6 @@ module RescueUniqueConstraint
|
|
|
34
38
|
else
|
|
35
39
|
raise "Database (#{database_name}) not supported"
|
|
36
40
|
end
|
|
37
|
-
)
|
|
38
41
|
end
|
|
39
42
|
|
|
40
43
|
def database_name
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'rescue_unique_constraint-p/version'
|
|
2
4
|
require 'rescue_unique_constraint-p/index'
|
|
3
5
|
require 'rescue_unique_constraint-p/rescue_handler'
|
|
@@ -17,7 +19,7 @@ module RescueUniqueConstraint
|
|
|
17
19
|
# methods mixed into ActiveRecord class
|
|
18
20
|
module ClassMethods
|
|
19
21
|
def index_rescue_handler
|
|
20
|
-
@
|
|
22
|
+
@index_rescue_handler ||= RescueUniqueConstraint::RescueHandler.new(self)
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
def rescue_unique_constraint(index:, field:)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
|
+
require 'rescue_unique_constraint-p/version'
|
|
6
|
+
|
|
7
|
+
Gem::Specification.new do |spec|
|
|
8
|
+
spec.name = 'rescue_unique_constraint-p'
|
|
9
|
+
spec.version = RescueUniqueConstraint::VERSION
|
|
10
|
+
spec.authors = ['Tam Dang', 'Yan Pritzker']
|
|
11
|
+
spec.email = ['tam.dang@reverb.com', 'yan@reverb.com']
|
|
12
|
+
spec.summary = 'Turns ActiveRecord::RecordNotUnique errors into ActiveRecord errors'
|
|
13
|
+
spec.description = 'Rescues unique constraint violations and turns them into ActiveRecord errors'
|
|
14
|
+
spec.homepage = 'https://github.com/plribeiro3000/rescue_unique_contraint'
|
|
15
|
+
spec.license = 'Apache-2.0'
|
|
16
|
+
|
|
17
|
+
spec.files = `git ls-files -z`.split("\x0")
|
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
20
|
+
spec.require_paths = ['lib']
|
|
21
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
|
22
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Thing < ActiveRecord::Base
|
|
4
|
+
include RescueUniqueConstraint
|
|
5
|
+
|
|
6
|
+
rescue_unique_constraint index: 'idx_things_on_name_unique', field: 'name'
|
|
7
|
+
rescue_unique_constraint index: 'idx_things_on_code_and_score_unique', field: 'score'
|
|
8
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe RescueUniqueConstraint do
|
|
6
|
+
let(:thing) { Thing.create(name: 'foo', code: 123, score: 1000) }
|
|
7
|
+
let(:another_thing) { Thing.new }
|
|
8
|
+
|
|
9
|
+
before { thing }
|
|
10
|
+
after { Thing.destroy_all }
|
|
11
|
+
|
|
12
|
+
context 'when single field value is duplicated' do
|
|
13
|
+
before do
|
|
14
|
+
another_thing.name = 'foo'
|
|
15
|
+
another_thing.save
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'does not save' do
|
|
19
|
+
expect(another_thing.persisted?).to be false
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'adds an error message to the defined attribute' do
|
|
23
|
+
expect(another_thing.errors[:name].first).to match(/has already been taken/)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
context 'when multiple field value is duplicated' do
|
|
28
|
+
before do
|
|
29
|
+
another_thing.score = 1000
|
|
30
|
+
another_thing.code = 123
|
|
31
|
+
another_thing.save
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'does not save' do
|
|
35
|
+
expect(another_thing.persisted?).to be false
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'adds an error message to the defined attribute' do
|
|
39
|
+
expect(another_thing.errors[:score].first).to match(/has already been taken/)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rspec'
|
|
4
|
+
require 'jazz_fingers'
|
|
5
|
+
|
|
6
|
+
RSpec.configure do |config|
|
|
7
|
+
# Disable RSpec exposing methods globally on `Module` and `main`
|
|
8
|
+
config.disable_monkey_patching!
|
|
9
|
+
|
|
10
|
+
config.expect_with :rspec do |c|
|
|
11
|
+
c.syntax = :expect
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
config.before do
|
|
15
|
+
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
|
|
16
|
+
ActiveRecord::Schema.verbose = false
|
|
17
|
+
|
|
18
|
+
ActiveRecord::Schema.define(version: 1) do
|
|
19
|
+
create_table :things do |t|
|
|
20
|
+
t.string :name
|
|
21
|
+
t.integer :code
|
|
22
|
+
t.integer :score
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
add_index :things, :name, unique: true, name: 'idx_things_on_name_unique'
|
|
26
|
+
add_index :things, %i[code score], unique: true, name: 'idx_things_on_code_and_score_unique'
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
JazzFingers.configure do |config|
|
|
32
|
+
config.colored_prompt = false
|
|
33
|
+
config.amazing_print = false
|
|
34
|
+
config.coolline = false
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
require File.expand_path('lib/rescue_unique_constraint-p')
|
|
38
|
+
require File.expand_path('spec/fake_app/thing')
|
metadata
CHANGED
|
@@ -1,134 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rescue_unique_constraint-p
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tam Dang
|
|
8
8
|
- Yan Pritzker
|
|
9
|
-
autorequire:
|
|
10
9
|
bindir: bin
|
|
11
10
|
cert_chain: []
|
|
12
|
-
date:
|
|
13
|
-
dependencies:
|
|
14
|
-
- !ruby/object:Gem::Dependency
|
|
15
|
-
name: activerecord
|
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
|
17
|
-
requirements:
|
|
18
|
-
- - ">="
|
|
19
|
-
- !ruby/object:Gem::Version
|
|
20
|
-
version: '3.2'
|
|
21
|
-
- - "<"
|
|
22
|
-
- !ruby/object:Gem::Version
|
|
23
|
-
version: '8'
|
|
24
|
-
type: :runtime
|
|
25
|
-
prerelease: false
|
|
26
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
27
|
-
requirements:
|
|
28
|
-
- - ">="
|
|
29
|
-
- !ruby/object:Gem::Version
|
|
30
|
-
version: '3.2'
|
|
31
|
-
- - "<"
|
|
32
|
-
- !ruby/object:Gem::Version
|
|
33
|
-
version: '8'
|
|
34
|
-
- !ruby/object:Gem::Dependency
|
|
35
|
-
name: bundler
|
|
36
|
-
requirement: !ruby/object:Gem::Requirement
|
|
37
|
-
requirements:
|
|
38
|
-
- - "~>"
|
|
39
|
-
- !ruby/object:Gem::Version
|
|
40
|
-
version: '2.2'
|
|
41
|
-
type: :development
|
|
42
|
-
prerelease: false
|
|
43
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
44
|
-
requirements:
|
|
45
|
-
- - "~>"
|
|
46
|
-
- !ruby/object:Gem::Version
|
|
47
|
-
version: '2.2'
|
|
48
|
-
- !ruby/object:Gem::Dependency
|
|
49
|
-
name: rake
|
|
50
|
-
requirement: !ruby/object:Gem::Requirement
|
|
51
|
-
requirements:
|
|
52
|
-
- - "~>"
|
|
53
|
-
- !ruby/object:Gem::Version
|
|
54
|
-
version: '10.5'
|
|
55
|
-
type: :development
|
|
56
|
-
prerelease: false
|
|
57
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
58
|
-
requirements:
|
|
59
|
-
- - "~>"
|
|
60
|
-
- !ruby/object:Gem::Version
|
|
61
|
-
version: '10.5'
|
|
62
|
-
- !ruby/object:Gem::Dependency
|
|
63
|
-
name: rspec
|
|
64
|
-
requirement: !ruby/object:Gem::Requirement
|
|
65
|
-
requirements:
|
|
66
|
-
- - "~>"
|
|
67
|
-
- !ruby/object:Gem::Version
|
|
68
|
-
version: '3.0'
|
|
69
|
-
type: :development
|
|
70
|
-
prerelease: false
|
|
71
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
72
|
-
requirements:
|
|
73
|
-
- - "~>"
|
|
74
|
-
- !ruby/object:Gem::Version
|
|
75
|
-
version: '3.0'
|
|
76
|
-
- !ruby/object:Gem::Dependency
|
|
77
|
-
name: sqlite3
|
|
78
|
-
requirement: !ruby/object:Gem::Requirement
|
|
79
|
-
requirements:
|
|
80
|
-
- - "~>"
|
|
81
|
-
- !ruby/object:Gem::Version
|
|
82
|
-
version: '1.3'
|
|
83
|
-
type: :development
|
|
84
|
-
prerelease: false
|
|
85
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
86
|
-
requirements:
|
|
87
|
-
- - "~>"
|
|
88
|
-
- !ruby/object:Gem::Version
|
|
89
|
-
version: '1.3'
|
|
90
|
-
- !ruby/object:Gem::Dependency
|
|
91
|
-
name: pry
|
|
92
|
-
requirement: !ruby/object:Gem::Requirement
|
|
93
|
-
requirements:
|
|
94
|
-
- - ">="
|
|
95
|
-
- !ruby/object:Gem::Version
|
|
96
|
-
version: '0'
|
|
97
|
-
type: :development
|
|
98
|
-
prerelease: false
|
|
99
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
100
|
-
requirements:
|
|
101
|
-
- - ">="
|
|
102
|
-
- !ruby/object:Gem::Version
|
|
103
|
-
version: '0'
|
|
104
|
-
- !ruby/object:Gem::Dependency
|
|
105
|
-
name: pry-byebug
|
|
106
|
-
requirement: !ruby/object:Gem::Requirement
|
|
107
|
-
requirements:
|
|
108
|
-
- - ">="
|
|
109
|
-
- !ruby/object:Gem::Version
|
|
110
|
-
version: '0'
|
|
111
|
-
type: :development
|
|
112
|
-
prerelease: false
|
|
113
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
114
|
-
requirements:
|
|
115
|
-
- - ">="
|
|
116
|
-
- !ruby/object:Gem::Version
|
|
117
|
-
version: '0'
|
|
118
|
-
- !ruby/object:Gem::Dependency
|
|
119
|
-
name: gem-release
|
|
120
|
-
requirement: !ruby/object:Gem::Requirement
|
|
121
|
-
requirements:
|
|
122
|
-
- - ">="
|
|
123
|
-
- !ruby/object:Gem::Version
|
|
124
|
-
version: '0'
|
|
125
|
-
type: :development
|
|
126
|
-
prerelease: false
|
|
127
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
128
|
-
requirements:
|
|
129
|
-
- - ">="
|
|
130
|
-
- !ruby/object:Gem::Version
|
|
131
|
-
version: '0'
|
|
11
|
+
date: 2025-02-06 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
132
13
|
description: Rescues unique constraint violations and turns them into ActiveRecord
|
|
133
14
|
errors
|
|
134
15
|
email:
|
|
@@ -143,8 +24,8 @@ files:
|
|
|
143
24
|
- ".ruby-gemset"
|
|
144
25
|
- ".ruby-version"
|
|
145
26
|
- Gemfile
|
|
27
|
+
- Gemfile.lock
|
|
146
28
|
- LICENSE.txt
|
|
147
|
-
- Makefile
|
|
148
29
|
- README.md
|
|
149
30
|
- Rakefile
|
|
150
31
|
- lib/rescue_unique_constraint-p.rb
|
|
@@ -154,13 +35,15 @@ files:
|
|
|
154
35
|
- lib/rescue_unique_constraint-p/index.rb
|
|
155
36
|
- lib/rescue_unique_constraint-p/rescue_handler.rb
|
|
156
37
|
- lib/rescue_unique_constraint-p/version.rb
|
|
157
|
-
- rescue_unique_constraint
|
|
158
|
-
- spec/
|
|
159
|
-
|
|
38
|
+
- rescue_unique_constraint.gemspec
|
|
39
|
+
- spec/fake_app/thing.rb
|
|
40
|
+
- spec/rescue_unique_constraint-p_spec.rb
|
|
41
|
+
- spec/spec_helper.rb
|
|
42
|
+
homepage: https://github.com/plribeiro3000/rescue_unique_contraint
|
|
160
43
|
licenses:
|
|
161
|
-
- Apache
|
|
162
|
-
metadata:
|
|
163
|
-
|
|
44
|
+
- Apache-2.0
|
|
45
|
+
metadata:
|
|
46
|
+
rubygems_mfa_required: 'true'
|
|
164
47
|
rdoc_options: []
|
|
165
48
|
require_paths:
|
|
166
49
|
- lib
|
|
@@ -175,9 +58,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
175
58
|
- !ruby/object:Gem::Version
|
|
176
59
|
version: '0'
|
|
177
60
|
requirements: []
|
|
178
|
-
rubygems_version: 3.
|
|
179
|
-
signing_key:
|
|
61
|
+
rubygems_version: 3.6.2
|
|
180
62
|
specification_version: 4
|
|
181
63
|
summary: Turns ActiveRecord::RecordNotUnique errors into ActiveRecord errors
|
|
182
64
|
test_files:
|
|
183
|
-
- spec/
|
|
65
|
+
- spec/fake_app/thing.rb
|
|
66
|
+
- spec/rescue_unique_constraint-p_spec.rb
|
|
67
|
+
- spec/spec_helper.rb
|
data/Makefile
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
# coding: utf-8
|
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
-
require 'rescue_unique_constraint-p/version'
|
|
5
|
-
|
|
6
|
-
Gem::Specification.new do |spec|
|
|
7
|
-
spec.name = "rescue_unique_constraint-p"
|
|
8
|
-
spec.version = RescueUniqueConstraint::VERSION
|
|
9
|
-
spec.authors = ["Tam Dang", "Yan Pritzker"]
|
|
10
|
-
spec.email = ["tam.dang@reverb.com","yan@reverb.com"]
|
|
11
|
-
spec.summary = %q{Turns ActiveRecord::RecordNotUnique errors into ActiveRecord errors}
|
|
12
|
-
spec.description = %q{Rescues unique constraint violations and turns them into ActiveRecord errors}
|
|
13
|
-
spec.homepage = "https://github.com/reverbdotcom/rescue_unique_contraint"
|
|
14
|
-
spec.license = "Apache 2.0"
|
|
15
|
-
|
|
16
|
-
spec.files = `git ls-files -z`.split("\x0")
|
|
17
|
-
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
18
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
19
|
-
spec.require_paths = ["lib"]
|
|
20
|
-
|
|
21
|
-
spec.add_dependency "activerecord", ">= 3.2", "< 8"
|
|
22
|
-
|
|
23
|
-
spec.add_development_dependency "bundler", "~> 2.2"
|
|
24
|
-
spec.add_development_dependency "rake", "~> 10.5"
|
|
25
|
-
spec.add_development_dependency "rspec", "~> 3.0"
|
|
26
|
-
spec.add_development_dependency "sqlite3", "~> 1.3"
|
|
27
|
-
spec.add_development_dependency 'pry'
|
|
28
|
-
spec.add_development_dependency 'pry-byebug'
|
|
29
|
-
spec.add_development_dependency 'gem-release'
|
|
30
|
-
end
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
require 'active_record'
|
|
2
|
-
require 'rescue_unique_constraint-p'
|
|
3
|
-
|
|
4
|
-
describe RescueUniqueConstraint do
|
|
5
|
-
before :all do
|
|
6
|
-
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
|
7
|
-
ActiveRecord::Schema.verbose = false
|
|
8
|
-
ActiveRecord::Schema.define(:version => 1) do
|
|
9
|
-
create_table :things do |t|
|
|
10
|
-
t.string :name
|
|
11
|
-
t.string :test
|
|
12
|
-
t.integer :code
|
|
13
|
-
t.integer :score
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
add_index :things, :name, unique: true, name: "idx_things_on_name_unique"
|
|
17
|
-
add_index :things, :test, unique: true, name: "idx_things_on_test_unique"
|
|
18
|
-
add_index :things, [:code, :score], unique: true, name: "idx_things_on_code_and_score_unique"
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
class Thing < ActiveRecord::Base
|
|
23
|
-
include RescueUniqueConstraint
|
|
24
|
-
rescue_unique_constraint index: "idx_things_on_name_unique", field: "name"
|
|
25
|
-
rescue_unique_constraint index: "idx_things_on_test_unique", field: "test"
|
|
26
|
-
rescue_unique_constraint index: "idx_things_on_code_and_score_unique", field: "score"
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
before :each do
|
|
30
|
-
Thing.destroy_all
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
it "rescues unique constraint violations as activerecord errors" do
|
|
34
|
-
thing = Thing.create(name: "foo", test: 'bar', code: 123, score: 1000)
|
|
35
|
-
dupe = Thing.new(name: "foo", test: 'baz', code: 456, score: 2000)
|
|
36
|
-
expect(dupe.save).to eql false
|
|
37
|
-
expect(dupe.errors.messages.keys).to contain_exactly(:name)
|
|
38
|
-
expect(dupe.errors[:name].first).to match /has already been taken/
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
it "adds error message to atrribute which caused unique-voilation" do
|
|
42
|
-
thing = Thing.create(name: "foo", test: 'bar', code: 123, score: 1000)
|
|
43
|
-
dupe = Thing.new(name: "lorem", test: 'bar', code: 456, score: 2000)
|
|
44
|
-
expect(dupe.save).to eql false
|
|
45
|
-
expect(dupe.errors.messages.keys).to contain_exactly(:test)
|
|
46
|
-
expect(dupe.errors[:test].first).to match /has already been taken/
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
context "When unique contraint is voilated by a composite index" do
|
|
50
|
-
it "adds error message to user defined atrribute" do
|
|
51
|
-
thing = Thing.create(name: "foo", test: 'bar', code: 123, score: 1000)
|
|
52
|
-
dupe = Thing.new(name: "lorem", test: 'ipsum', code: 123, score: 1000)
|
|
53
|
-
expect(dupe.save).to eql false
|
|
54
|
-
expect(dupe.errors.messages.keys).to contain_exactly(:score)
|
|
55
|
-
expect(dupe.errors[:score].first).to match /has already been taken/
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|