rescue_unique_constraint 1.4.0 → 1.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: ea30803708b58175b2ea038bb6ebcb03b69d8db9
4
- data.tar.gz: e28a19b92f52f1a71ec80e21b9a5f2ef5ca02e91
2
+ SHA256:
3
+ metadata.gz: 5f12a5f4ccf1af041c90798ddde6b3f8f8b548cdbc2993b692dcf443d25d09ef
4
+ data.tar.gz: 6a7e89ed993cf44c928db9725018ded393744c0b77880228e6f53b40433ed614
5
5
  SHA512:
6
- metadata.gz: e0d875de50c7fe791881a78812d1c3bd6521ecf0b794acf3dc16ba067b5229a6f0648f96c1ebfcfebe5077e8b565be414ef95e592cfe126a7c51e6b1b51ca6a0
7
- data.tar.gz: 4e8118681c357af946e7fc0cae167a96e4e90d2faaa46ec285bdc45078dfb5a990d77580ffd77bace0570f8b8465cc96773b050e709b80363a680d4e06771604
6
+ metadata.gz: b84fb7fba8e0337d08ac29daaa4620ade43460ac004bedb4dba0ef8e492850c226dab1daa094f0ee4d2e3285b1e5ff040ed2c2b43251fcc0ffdf22e1e2dce7d9
7
+ data.tar.gz: f3afed3102872303e40808aa92a314e1831dffc3b77cc83506ce7a2c39b54293f9c86026634ca5413b030b250ae1565ce8b259eb74535b5e166582f550b1c6a0
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.5.1
@@ -1,8 +1,18 @@
1
1
  module RescueUniqueConstraint
2
2
  module Adapter
3
3
  class SqliteAdapter
4
+ def initialize(table_name)
5
+ @table_name = table_name
6
+ end
7
+
8
+ # Sample error message returned by ActiveRecord for Sqlite Unique exception:
9
+ # 'SQLite3::ConstraintException: UNIQUE constraint failed: things.code, things.score: INSERT INTO "things" ("name", "test", "code", "score") VALUES (?, ?, ?, ?)'
10
+ #
11
+ # Step1: extract column names from above message on which unique constraint failed.
12
+ # Step2: Check if this index's field is among those columns.
4
13
  def index_error?(index, error_message)
5
- error_message[/UNIQUE.*#{index.field}/]
14
+ column_names = error_message.scan(%r{(?<=#{@table_name}\.)\w+})
15
+ column_names.include?(index.field)
6
16
  end
7
17
  end
8
18
  end
@@ -30,7 +30,7 @@ module RescueUniqueConstraint
30
30
  when :postgresql
31
31
  Adapter::PostgresqlAdapter.new
32
32
  when :sqlite
33
- Adapter::SqliteAdapter.new
33
+ Adapter::SqliteAdapter.new(@model.table_name)
34
34
  else
35
35
  raise "Database (#{database_name}) not supported"
36
36
  end
@@ -1,3 +1,3 @@
1
1
  module RescueUniqueConstraint
2
- VERSION = "1.4.0"
2
+ VERSION = "1.5.0"
3
3
  end
@@ -26,4 +26,5 @@ Gem::Specification.new do |spec|
26
26
  spec.add_development_dependency "sqlite3", "~> 1.3"
27
27
  spec.add_development_dependency 'pry'
28
28
  spec.add_development_dependency 'pry-byebug'
29
+ spec.add_development_dependency 'gem-release'
29
30
  end
@@ -2,17 +2,20 @@ require 'active_record'
2
2
  require 'rescue_unique_constraint'
3
3
 
4
4
  describe RescueUniqueConstraint do
5
- before do
5
+ before :all do
6
6
  ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
7
7
  ActiveRecord::Schema.verbose = false
8
8
  ActiveRecord::Schema.define(:version => 1) do
9
9
  create_table :things do |t|
10
10
  t.string :name
11
11
  t.string :test
12
+ t.integer :code
13
+ t.integer :score
12
14
  end
13
15
 
14
16
  add_index :things, :name, unique: true, name: "idx_things_on_name_unique"
15
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"
16
19
  end
17
20
  end
18
21
 
@@ -20,13 +23,36 @@ describe RescueUniqueConstraint do
20
23
  include RescueUniqueConstraint
21
24
  rescue_unique_constraint index: "idx_things_on_name_unique", field: "name"
22
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
23
31
  end
24
32
 
25
33
  it "rescues unique constraint violations as activerecord errors" do
26
- thing = Thing.create(name: "foo", test: 'bar')
27
- dupe = Thing.new(name: "foo", test: 'bar')
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)
28
44
  expect(dupe.save).to eql false
29
- expect(dupe.errors[:name].first).to match /taken/
30
- expect(dupe.errors[:test].first).to match /taken/
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
31
57
  end
32
58
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rescue_unique_constraint
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tam Dang
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-01-23 00:00:00.000000000 Z
12
+ date: 2018-10-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -115,6 +115,20 @@ dependencies:
115
115
  - - ">="
116
116
  - !ruby/object:Gem::Version
117
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'
118
132
  description: Rescues unique constraint violations and turns them into ActiveRecord
119
133
  errors
120
134
  email:
@@ -126,6 +140,7 @@ extra_rdoc_files: []
126
140
  files:
127
141
  - ".gitignore"
128
142
  - ".rubocop.yml"
143
+ - ".ruby-version"
129
144
  - Gemfile
130
145
  - LICENSE.txt
131
146
  - README.md
@@ -159,7 +174,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
159
174
  version: '0'
160
175
  requirements: []
161
176
  rubyforge_project:
162
- rubygems_version: 2.6.13
177
+ rubygems_version: 2.7.6
163
178
  signing_key:
164
179
  specification_version: 4
165
180
  summary: Turns ActiveRecord::RecordNotUnique errors into ActiveRecord errors