activerecord-rescue_from_duplicate 0.1.5 → 0.2.6
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/.github/workflows/ci.yml +41 -0
- data/.github/workflows/cla.yml +24 -0
- data/README.md +1 -3
- data/activerecord-rescue_from_duplicate.gemspec +1 -1
- data/lib/rescue_from_duplicate/active_record/extension.rb +7 -4
- data/lib/rescue_from_duplicate/active_record/version.rb +1 -1
- data/lib/rescue_from_duplicate/active_record.rb +1 -1
- data/spec/rescue_from_duplicate_spec.rb +9 -1
- data/spec/support/model.rb +2 -2
- metadata +7 -6
- data/.travis.yml +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5e6132feb5c01f32d458d37eeccdc5551263280c72040d5718e10d53795d9c98
|
4
|
+
data.tar.gz: 5f9e6a0f3a05e9ced301db7f25f51176292af0fa33f0c9fe3dc3b91f7bceaef3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '09bdf44118974354a00a74635d8b3b277f85bb9adf8d1fc48a186699962de82e834fef26ac5dc599a7b039c085eeb30815f900649e7ab0c5a33c4510fa3e5ede'
|
7
|
+
data.tar.gz: 03bc4fe8d528ab693e0619114af9662fecc5dcf914ce41ca5b1c8c98613f9c893afea72e5f6b5de303c7ef50324c9c83da107f807a1d9b54f69a92cfbd96705b
|
@@ -0,0 +1,41 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on: [push, pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
build:
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
name: Ruby ${{ matrix.ruby }}
|
9
|
+
services:
|
10
|
+
postgres:
|
11
|
+
image: postgres
|
12
|
+
env:
|
13
|
+
POSTGRES_USER: "test"
|
14
|
+
POSTGRES_PASSWORD: "test"
|
15
|
+
POSTGRES_DB: "rescue_from_duplicate"
|
16
|
+
ports:
|
17
|
+
- "5432:5432"
|
18
|
+
mysql:
|
19
|
+
image: mysql:8.0
|
20
|
+
env:
|
21
|
+
MYSQL_USER: "test"
|
22
|
+
MYSQL_PASSWORD: "test"
|
23
|
+
MYSQL_ALLOW_EMPTY_PASSWORD: "true"
|
24
|
+
MYSQL_DATABASE: "rescue_from_duplicate"
|
25
|
+
ports:
|
26
|
+
- "3306:3306"
|
27
|
+
strategy:
|
28
|
+
fail-fast: false
|
29
|
+
matrix:
|
30
|
+
ruby: ["3.2"]
|
31
|
+
steps:
|
32
|
+
- name: Check out code
|
33
|
+
uses: actions/checkout@v4
|
34
|
+
- name: Set up Ruby ${{ matrix.ruby }}
|
35
|
+
uses: ruby/setup-ruby@v1
|
36
|
+
with:
|
37
|
+
ruby-version: ${{ matrix.ruby }}
|
38
|
+
bundler-cache: true
|
39
|
+
cache-version: 1
|
40
|
+
- name: Tests
|
41
|
+
run: bundle exec rake
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# .github/workflows/cla.yml
|
2
|
+
name: Contributor License Agreement (CLA)
|
3
|
+
|
4
|
+
on:
|
5
|
+
pull_request_target:
|
6
|
+
types: [opened, synchronize]
|
7
|
+
issue_comment:
|
8
|
+
types: [created]
|
9
|
+
|
10
|
+
jobs:
|
11
|
+
cla:
|
12
|
+
runs-on: ubuntu-latest
|
13
|
+
if: |
|
14
|
+
(github.event.issue.pull_request
|
15
|
+
&& !github.event.issue.pull_request.merged_at
|
16
|
+
&& contains(github.event.comment.body, 'signed')
|
17
|
+
)
|
18
|
+
|| (github.event.pull_request && !github.event.pull_request.merged)
|
19
|
+
steps:
|
20
|
+
- uses: Shopify/shopify-cla-action@v1
|
21
|
+
with:
|
22
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
23
|
+
cla-token: ${{ secrets.CLA_TOKEN }}
|
24
|
+
|
data/README.md
CHANGED
@@ -10,8 +10,6 @@ Additionally, a macro allows you to assume that the record will be unique and re
|
|
10
10
|
|
11
11
|
Tested with:
|
12
12
|
|
13
|
-
- ActiveRecord: 3.2, 4.0, 4.1, 4.2, edge
|
14
|
-
- Ruby 1.9.3, 2.0.0, 2.1.2
|
15
13
|
- MySQL, PostgreSQL, Sqlite3
|
16
14
|
|
17
15
|
**Note:**
|
@@ -69,7 +67,7 @@ And then execute:
|
|
69
67
|
Or install it yourself as:
|
70
68
|
|
71
69
|
$ gem install activerecord-rescue_from_duplicate
|
72
|
-
|
70
|
+
|
73
71
|
## Development Setup
|
74
72
|
|
75
73
|
Install:
|
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_dependency "activerecord", ">=
|
21
|
+
spec.add_dependency "activerecord", ">= 7"
|
22
22
|
|
23
23
|
spec.add_development_dependency "bundler"
|
24
24
|
spec.add_development_dependency "rake"
|
@@ -38,16 +38,19 @@ module RescueFromDuplicate::ActiveRecord
|
|
38
38
|
attribute = handler.attributes.first
|
39
39
|
options = handler.options.except(:case_sensitive, :scope).merge(value: self.send(:read_attribute_for_validation, attribute))
|
40
40
|
|
41
|
-
self.errors.add(attribute, :taken, options)
|
41
|
+
self.errors.add(attribute, :taken, **options)
|
42
42
|
true
|
43
43
|
end
|
44
44
|
|
45
45
|
def exception_handler(exception)
|
46
|
+
handlers = self.class._rescue_from_duplicate_handlers
|
47
|
+
return if handlers.empty?
|
48
|
+
|
46
49
|
columns = exception_columns(exception)
|
47
50
|
return unless columns
|
48
51
|
columns = columns.sort
|
49
52
|
|
50
|
-
|
53
|
+
handlers.detect do |handler|
|
51
54
|
handler.rescue? && columns == handler.columns
|
52
55
|
end
|
53
56
|
end
|
@@ -67,7 +70,7 @@ module RescueFromDuplicate::ActiveRecord
|
|
67
70
|
end
|
68
71
|
|
69
72
|
def sqlite3_exception_columns(exception)
|
70
|
-
extract_columns(exception.message[/columns? (.*) (?:is|are) not unique/, 1]) ||
|
73
|
+
extract_columns(exception.message[/columns? (.*) (?:is|are) not unique/, 1]) ||
|
71
74
|
extract_columns(exception.message[/UNIQUE constraint failed: ([^:]*)\:?/, 1])
|
72
75
|
end
|
73
76
|
|
@@ -77,7 +80,7 @@ module RescueFromDuplicate::ActiveRecord
|
|
77
80
|
end
|
78
81
|
|
79
82
|
def other_exception_columns(exception)
|
80
|
-
indexes = self.class.connection.indexes(self.class.table_name)
|
83
|
+
indexes = self.class.connection.schema_cache.indexes(self.class.table_name)
|
81
84
|
indexes.detect{ |i| exception.message.include?(i.name) }.try(:columns) || []
|
82
85
|
end
|
83
86
|
end
|
@@ -16,7 +16,7 @@ module RescueFromDuplicate
|
|
16
16
|
klasses.each do |klass|
|
17
17
|
klass._rescue_from_duplicate_handlers.each do |handler|
|
18
18
|
next unless klass.connection.table_exists?(klass.table_name)
|
19
|
-
unique_indexes = klass.connection.indexes(klass.table_name).select(&:unique)
|
19
|
+
unique_indexes = klass.connection.schema_cache.indexes(klass.table_name).select(&:unique)
|
20
20
|
|
21
21
|
unless unique_indexes.any? { |index| index.columns.map(&:to_s).sort == handler.columns }
|
22
22
|
missing_unique_indexes << MissingUniqueIndex.new(klass, handler.attributes, handler.columns)
|
@@ -7,7 +7,8 @@ shared_examples 'database error rescuing' do
|
|
7
7
|
subject { Rescuable.new }
|
8
8
|
|
9
9
|
before do
|
10
|
-
|
10
|
+
connection = double(schema_cache: double(indexes: [Rescuable.index]))
|
11
|
+
allow(Rescuable).to(receive(:connection).and_return(connection))
|
11
12
|
end
|
12
13
|
|
13
14
|
describe "#create_or_update when the validation fails" do
|
@@ -26,6 +27,13 @@ shared_examples 'database error rescuing' do
|
|
26
27
|
it "raises an exception" do
|
27
28
|
expect { subject.create_or_update }.to raise_error(ActiveRecord::RecordNotUnique)
|
28
29
|
end
|
30
|
+
|
31
|
+
it "doesn't parse the message" do
|
32
|
+
allow(uniqueness_exception).to(
|
33
|
+
receive(:message).and_raise(StandardError, "Message should not have been accessed")
|
34
|
+
)
|
35
|
+
expect { subject.create_or_update }.to raise_error(ActiveRecord::RecordNotUnique)
|
36
|
+
end
|
29
37
|
end
|
30
38
|
end
|
31
39
|
|
data/spec/support/model.rb
CHANGED
@@ -13,7 +13,7 @@ CONNECTIONS = {
|
|
13
13
|
username: "test",
|
14
14
|
password: "test",
|
15
15
|
host: "127.0.0.1",
|
16
|
-
port: "
|
16
|
+
port: "5432",
|
17
17
|
},
|
18
18
|
test_mysql: {
|
19
19
|
adapter: "mysql2",
|
@@ -21,7 +21,7 @@ CONNECTIONS = {
|
|
21
21
|
username: "test",
|
22
22
|
password: "test",
|
23
23
|
host: "127.0.0.1",
|
24
|
-
port: "
|
24
|
+
port: "3306",
|
25
25
|
},
|
26
26
|
}
|
27
27
|
class CreateAllTables < ActiveRecord::Migration[5.2]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-rescue_from_duplicate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Guillaume Malette
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-12-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '7'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '7'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -143,9 +143,10 @@ executables: []
|
|
143
143
|
extensions: []
|
144
144
|
extra_rdoc_files: []
|
145
145
|
files:
|
146
|
+
- ".github/workflows/ci.yml"
|
147
|
+
- ".github/workflows/cla.yml"
|
146
148
|
- ".gitignore"
|
147
149
|
- ".rspec"
|
148
|
-
- ".travis.yml"
|
149
150
|
- Gemfile
|
150
151
|
- LICENSE.txt
|
151
152
|
- README.md
|
@@ -186,7 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
186
187
|
- !ruby/object:Gem::Version
|
187
188
|
version: '0'
|
188
189
|
requirements: []
|
189
|
-
rubygems_version: 3.
|
190
|
+
rubygems_version: 3.4.22
|
190
191
|
signing_key:
|
191
192
|
specification_version: 4
|
192
193
|
summary: Rescue from MySQL and Sqlite duplicate errors when trying to insert records
|
data/.travis.yml
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
sudo: false
|
2
|
-
rvm:
|
3
|
-
- '2.5'
|
4
|
-
- '2.6'
|
5
|
-
- '2.7'
|
6
|
-
|
7
|
-
env:
|
8
|
-
- DOCKER_COMPOSE_VERSION=1.20.1
|
9
|
-
|
10
|
-
before_script:
|
11
|
-
- docker-compose --version
|
12
|
-
- docker-compose pull
|
13
|
-
- docker-compose build
|
14
|
-
- docker-compose up --no-start
|
15
|
-
- docker-compose start
|
16
|
-
- sleep 30 # Wait for databases to come online
|
17
|
-
- docker ps
|
18
|
-
|