has_unique_attribute 0.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 +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.rubocop.yml +152 -0
- data/.travis.yml +7 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +62 -0
- data/README.md +99 -0
- data/Rakefile +8 -0
- data/bin/console +14 -0
- data/bin/rspec +29 -0
- data/bin/rubocop +29 -0
- data/bin/setup +8 -0
- data/has_unique_attribute.gemspec +37 -0
- data/lib/has_unique_attribute.rb +73 -0
- data/lib/has_unique_attribute/version.rb +5 -0
- metadata +142 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 20a15d8b6e775b27196202f55a3620d7657649d95d3b4e82f817fc6ca56724a1
|
4
|
+
data.tar.gz: 19a566b7c92567464f326e9495b981f95bc04b99978b9913412ddf4997770545
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 48fc6ccdfd69432ecb1b7f4bd09071a697d21f5f07833e9e458f5da4b143e65ca79743b102f7c1af7127dcc9d4ede19c911aa7d2046817ce9022bf1c6d36b0f7
|
7
|
+
data.tar.gz: 17f07885a4303072c3e5517dded25e601d0ca6b9602339d99e56c5e68e87be6c5fb2cfb32acdcb221d549274434da1d4c1b55370e84acb93f968d1d39a3d2d89
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
require:
|
2
|
+
- rubocop-performance
|
3
|
+
- rubocop-rspec
|
4
|
+
|
5
|
+
AllCops:
|
6
|
+
DefaultFormatter: progress
|
7
|
+
DisplayCopNames: true
|
8
|
+
ExtraDetails: true
|
9
|
+
TargetRubyVersion: 2.6
|
10
|
+
Exclude:
|
11
|
+
- 'bin/*'
|
12
|
+
|
13
|
+
Layout/AccessModifierIndentation:
|
14
|
+
EnforcedStyle: outdent
|
15
|
+
|
16
|
+
Layout/EmptyLinesAroundAttributeAccessor:
|
17
|
+
Enabled: true
|
18
|
+
|
19
|
+
Layout/ExtraSpacing:
|
20
|
+
AllowForAlignment: true
|
21
|
+
|
22
|
+
Layout/HashAlignment:
|
23
|
+
EnforcedColonStyle: table
|
24
|
+
EnforcedHashRocketStyle: table
|
25
|
+
|
26
|
+
Layout/LineLength:
|
27
|
+
Max: 120
|
28
|
+
|
29
|
+
Layout/MultilineMethodCallIndentation:
|
30
|
+
EnforcedStyle: indented
|
31
|
+
|
32
|
+
Layout/SpaceAroundMethodCallOperator:
|
33
|
+
Enabled: true
|
34
|
+
|
35
|
+
Layout/SpaceInLambdaLiteral:
|
36
|
+
EnforcedStyle: require_space
|
37
|
+
|
38
|
+
Lint/AmbiguousBlockAssociation:
|
39
|
+
Enabled: false
|
40
|
+
|
41
|
+
Lint/DeprecatedOpenSSLConstant:
|
42
|
+
Enabled: true
|
43
|
+
|
44
|
+
Lint/DuplicateElsifCondition:
|
45
|
+
Enabled: true
|
46
|
+
|
47
|
+
Lint/MixedRegexpCaptureTypes:
|
48
|
+
Enabled: true
|
49
|
+
|
50
|
+
Lint/RaiseException:
|
51
|
+
Enabled: true
|
52
|
+
|
53
|
+
Lint/StructNewOverride:
|
54
|
+
Enabled: true
|
55
|
+
|
56
|
+
Metrics/BlockLength:
|
57
|
+
Exclude:
|
58
|
+
- 'spec/**/*'
|
59
|
+
|
60
|
+
Naming/RescuedExceptionsVariableName:
|
61
|
+
PreferredName: error
|
62
|
+
|
63
|
+
Performance/AncestorsInclude:
|
64
|
+
Enabled: true
|
65
|
+
|
66
|
+
Performance/BigDecimalWithNumericArgument:
|
67
|
+
Enabled: true
|
68
|
+
|
69
|
+
Performance/RedundantSortBlock:
|
70
|
+
Enabled: true
|
71
|
+
|
72
|
+
Performance/RedundantStringChars:
|
73
|
+
Enabled: true
|
74
|
+
|
75
|
+
Performance/ReverseFirst:
|
76
|
+
Enabled: true
|
77
|
+
|
78
|
+
Performance/SortReverse:
|
79
|
+
Enabled: true
|
80
|
+
|
81
|
+
Performance/Squeeze:
|
82
|
+
Enabled: true
|
83
|
+
|
84
|
+
Performance/StringInclude:
|
85
|
+
Enabled: true
|
86
|
+
|
87
|
+
RSpec/ExpectChange:
|
88
|
+
EnforcedStyle: block
|
89
|
+
|
90
|
+
RSpec/HookArgument:
|
91
|
+
EnforcedStyle: each
|
92
|
+
|
93
|
+
RSpec/NestedGroups:
|
94
|
+
Max: 5
|
95
|
+
|
96
|
+
Style/AccessorGrouping:
|
97
|
+
Enabled: true
|
98
|
+
|
99
|
+
Style/ArrayCoercion:
|
100
|
+
Enabled: true
|
101
|
+
|
102
|
+
Style/BisectedAttrAccessor:
|
103
|
+
Enabled: true
|
104
|
+
|
105
|
+
Style/CaseLikeIf:
|
106
|
+
Enabled: true
|
107
|
+
|
108
|
+
Style/ClassAndModuleChildren:
|
109
|
+
SafeAutoCorrect: true
|
110
|
+
|
111
|
+
Style/Documentation:
|
112
|
+
Enabled: false
|
113
|
+
|
114
|
+
Style/ExponentialNotation:
|
115
|
+
Enabled: true
|
116
|
+
|
117
|
+
Style/FrozenStringLiteralComment:
|
118
|
+
Safe: true
|
119
|
+
|
120
|
+
Style/HashAsLastArrayItem:
|
121
|
+
Enabled: true
|
122
|
+
|
123
|
+
Style/HashEachMethods:
|
124
|
+
Enabled: true
|
125
|
+
|
126
|
+
Style/HashLikeCase:
|
127
|
+
Enabled: true
|
128
|
+
|
129
|
+
Style/HashTransformKeys:
|
130
|
+
Enabled: true
|
131
|
+
|
132
|
+
Style/HashTransformValues:
|
133
|
+
Enabled: true
|
134
|
+
|
135
|
+
Style/RedundantAssignment:
|
136
|
+
Enabled: true
|
137
|
+
|
138
|
+
Style/RedundantFetchBlock:
|
139
|
+
Enabled: true
|
140
|
+
Safe: true
|
141
|
+
|
142
|
+
Style/RedundantFileExtensionInRequire:
|
143
|
+
Enabled: true
|
144
|
+
|
145
|
+
Style/RedundantRegexpCharacterClass:
|
146
|
+
Enabled: true
|
147
|
+
|
148
|
+
Style/RedundantRegexpEscape:
|
149
|
+
Enabled: true
|
150
|
+
|
151
|
+
Style/SlicingWithRange:
|
152
|
+
Enabled: true
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
has_unique_attribute (0.1.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
ast (2.4.1)
|
10
|
+
diff-lcs (1.4.4)
|
11
|
+
parallel (1.19.2)
|
12
|
+
parser (2.7.1.4)
|
13
|
+
ast (~> 2.4.1)
|
14
|
+
rainbow (3.0.0)
|
15
|
+
rake (13.0.1)
|
16
|
+
regexp_parser (1.7.1)
|
17
|
+
rexml (3.2.4)
|
18
|
+
rspec (3.9.0)
|
19
|
+
rspec-core (~> 3.9.0)
|
20
|
+
rspec-expectations (~> 3.9.0)
|
21
|
+
rspec-mocks (~> 3.9.0)
|
22
|
+
rspec-core (3.9.2)
|
23
|
+
rspec-support (~> 3.9.3)
|
24
|
+
rspec-expectations (3.9.2)
|
25
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
26
|
+
rspec-support (~> 3.9.0)
|
27
|
+
rspec-mocks (3.9.1)
|
28
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
29
|
+
rspec-support (~> 3.9.0)
|
30
|
+
rspec-support (3.9.3)
|
31
|
+
rubocop (0.88.0)
|
32
|
+
parallel (~> 1.10)
|
33
|
+
parser (>= 2.7.1.1)
|
34
|
+
rainbow (>= 2.2.2, < 4.0)
|
35
|
+
regexp_parser (>= 1.7)
|
36
|
+
rexml
|
37
|
+
rubocop-ast (>= 0.1.0, < 1.0)
|
38
|
+
ruby-progressbar (~> 1.7)
|
39
|
+
unicode-display_width (>= 1.4.0, < 2.0)
|
40
|
+
rubocop-ast (0.1.0)
|
41
|
+
parser (>= 2.7.0.1)
|
42
|
+
rubocop-performance (1.7.0)
|
43
|
+
rubocop (>= 0.82.0)
|
44
|
+
rubocop-rspec (1.42.0)
|
45
|
+
rubocop (>= 0.87.0)
|
46
|
+
ruby-progressbar (1.10.1)
|
47
|
+
unicode-display_width (1.7.0)
|
48
|
+
|
49
|
+
PLATFORMS
|
50
|
+
ruby
|
51
|
+
|
52
|
+
DEPENDENCIES
|
53
|
+
bundler (~> 2.0)
|
54
|
+
has_unique_attribute!
|
55
|
+
rake (~> 13.0)
|
56
|
+
rspec (~> 3.0)
|
57
|
+
rubocop
|
58
|
+
rubocop-performance
|
59
|
+
rubocop-rspec
|
60
|
+
|
61
|
+
BUNDLED WITH
|
62
|
+
2.0.2
|
data/README.md
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
# Has Unique Attribute
|
2
|
+
|
3
|
+
Applies validation errors to ActiveRecord model attributes when database uniqueness constraints fail.
|
4
|
+
|
5
|
+
**NOTE:** At the moment, only PostgreSQL is supported.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'has_unique_attribute'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install has_unique_attribute
|
22
|
+
|
23
|
+
Then, make it available to your models:
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
class ApplicationRecord < ActiveRecord::Base
|
27
|
+
extend HasUniqueAttribute
|
28
|
+
|
29
|
+
# ...
|
30
|
+
end
|
31
|
+
```
|
32
|
+
|
33
|
+
## Usage
|
34
|
+
|
35
|
+
Use the `has_unique_attribute` helper to add a handler to your model:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
class User < ApplicationRecord
|
39
|
+
has_unique_attribute :email
|
40
|
+
end
|
41
|
+
```
|
42
|
+
|
43
|
+
This will match errors on an index name `index_users_on_email` and add validation errors to the `email` attribute.
|
44
|
+
|
45
|
+
### Specifying an Index Name
|
46
|
+
|
47
|
+
To customize the name of the index matched, use the `index` option:
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
class User < ApplicationRecord
|
51
|
+
has_unique_attribute :email, index: 'custom_index_name'
|
52
|
+
end
|
53
|
+
```
|
54
|
+
|
55
|
+
### Customizing the Error Message
|
56
|
+
|
57
|
+
To customize the error message applied, use the `message` option:
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
class Project < ApplicationRecord
|
61
|
+
has_unique_attribute :name, message: 'already exists'
|
62
|
+
end
|
63
|
+
```
|
64
|
+
|
65
|
+
It's also possible to specify an I18n key for a translation:
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
class Project < ApplicationRecord
|
69
|
+
has_unique_attribute :name, message: :duplicate
|
70
|
+
end
|
71
|
+
```
|
72
|
+
|
73
|
+
By default, the `:taken` error translation is applied to attributes.
|
74
|
+
This mimics the behaviour of the `uniqueness` validator.
|
75
|
+
|
76
|
+
### Handling Composite Indexes
|
77
|
+
|
78
|
+
Composite (multi-column) indexes will need the index name to be specified explicitly:
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
class Membership < Application
|
82
|
+
belongs_to :user
|
83
|
+
belongs_to :club
|
84
|
+
|
85
|
+
has_unique_index :user, index: 'index_memberships_on_club_id_and_user_id', message: 'is already a member'
|
86
|
+
end
|
87
|
+
```
|
88
|
+
|
89
|
+
The error is only applied to the specified attribute.
|
90
|
+
|
91
|
+
## Development
|
92
|
+
|
93
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
94
|
+
|
95
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
96
|
+
|
97
|
+
## Contributing
|
98
|
+
|
99
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/Mihail-K/has_unique_attribute.
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "has_unique_attribute"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/rspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'rspec' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
require "pathname"
|
12
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
13
|
+
Pathname.new(__FILE__).realpath)
|
14
|
+
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
require "rubygems"
|
27
|
+
require "bundler/setup"
|
28
|
+
|
29
|
+
load Gem.bin_path("rspec-core", "rspec")
|
data/bin/rubocop
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'rubocop' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
require "pathname"
|
12
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
13
|
+
Pathname.new(__FILE__).realpath)
|
14
|
+
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
require "rubygems"
|
27
|
+
require "bundler/setup"
|
28
|
+
|
29
|
+
load Gem.bin_path("rubocop", "rubocop")
|
data/bin/setup
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
require 'has_unique_attribute/version'
|
7
|
+
|
8
|
+
Gem::Specification.new do |spec|
|
9
|
+
spec.name = 'has_unique_attribute'
|
10
|
+
spec.version = HasUniqueAttribute::VERSION
|
11
|
+
spec.authors = ['Mihail-K']
|
12
|
+
spec.email = []
|
13
|
+
|
14
|
+
spec.summary = 'Handle unique attributes safely using the database.'
|
15
|
+
spec.description = 'Adds custom handling for database uniqueness constraints to ActiveRecord.'
|
16
|
+
spec.homepage = 'https://github.com/Mihail-K/has_unique_attribute'
|
17
|
+
|
18
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
19
|
+
spec.metadata['source_code_uri'] = 'https://github.com/Mihail-K/has_unique_attribute'
|
20
|
+
|
21
|
+
# Specify which files should be added to the gem when it is released.
|
22
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
23
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
24
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
25
|
+
end
|
26
|
+
|
27
|
+
spec.bindir = 'exe'
|
28
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
29
|
+
spec.require_paths = ['lib']
|
30
|
+
|
31
|
+
spec.add_development_dependency 'bundler', '~> 2.0'
|
32
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
33
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
34
|
+
spec.add_development_dependency 'rubocop'
|
35
|
+
spec.add_development_dependency 'rubocop-performance'
|
36
|
+
spec.add_development_dependency 'rubocop-rspec'
|
37
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module HasUniqueAttribute
|
4
|
+
# @param attribute_name [String]
|
5
|
+
# @param index [String]
|
6
|
+
# @param message [Symbol, String]
|
7
|
+
# @return [void]
|
8
|
+
def has_unique_attribute(attribute_name, # rubocop:disable Naming/PredicateName
|
9
|
+
index: default_index_name_for_attribute(attribute_name),
|
10
|
+
message: :taken)
|
11
|
+
assert_unique_index_defined!(index)
|
12
|
+
|
13
|
+
handle_unique_attribute_on_save(attribute_name, index, message)
|
14
|
+
handle_unique_attribute_on_save!(attribute_name, index, message)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
# @param index_name [String]
|
20
|
+
# @return [void]
|
21
|
+
def assert_unique_index_defined!(index_name)
|
22
|
+
index = connection.indexes(table_name).find { |index_definition| index_definition.name == index_name }
|
23
|
+
|
24
|
+
raise ArgumentError, "#{name} does not have index: `#{index_name}`" if index.nil?
|
25
|
+
raise ArgumentError, "#{name} defines an index `#{index_name}`, but it is not unique" unless index.unique
|
26
|
+
end
|
27
|
+
|
28
|
+
# @param attribute_name [String]
|
29
|
+
# @return [String]
|
30
|
+
def default_index_name_for_attribute(attribute_name)
|
31
|
+
"index_#{table_name}_on_#{attribute_name}"
|
32
|
+
end
|
33
|
+
|
34
|
+
# @param attribute_name [String]
|
35
|
+
# @param index_name [String]
|
36
|
+
# @param message [Symbol, String]
|
37
|
+
# @return [void]
|
38
|
+
def handle_unique_attribute_on_save(attribute_name, index_name, message)
|
39
|
+
existing_method = instance_method(:save)
|
40
|
+
|
41
|
+
define_method(:save) do |*args|
|
42
|
+
existing_method.bind(self).call(*args)
|
43
|
+
rescue ActiveRecord::RecordNotUnique => error
|
44
|
+
if error.message.include?(index_name)
|
45
|
+
errors.add(attribute_name, message)
|
46
|
+
|
47
|
+
return false
|
48
|
+
end
|
49
|
+
|
50
|
+
raise error
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# @param attribute_name [String]
|
55
|
+
# @param index_name [String]
|
56
|
+
# @param message [Symbol, String]
|
57
|
+
# @return [void]
|
58
|
+
def handle_unique_attribute_on_save!(attribute_name, index_name, message)
|
59
|
+
existing_method = instance_method(:save!)
|
60
|
+
|
61
|
+
define_method(:save!) do |*args|
|
62
|
+
existing_method.bind(self).call(*args)
|
63
|
+
rescue ActiveRecord::RecordNotUnique => error
|
64
|
+
if error.message.include?(index_name)
|
65
|
+
errors.add(attribute_name, message)
|
66
|
+
|
67
|
+
raise ActiveRecord::RecordInvalid, self
|
68
|
+
end
|
69
|
+
|
70
|
+
raise error
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
metadata
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: has_unique_attribute
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mihail-K
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-07-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '13.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '13.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop-performance
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop-rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: Adds custom handling for database uniqueness constraints to ActiveRecord.
|
98
|
+
email: []
|
99
|
+
executables: []
|
100
|
+
extensions: []
|
101
|
+
extra_rdoc_files: []
|
102
|
+
files:
|
103
|
+
- ".gitignore"
|
104
|
+
- ".rspec"
|
105
|
+
- ".rubocop.yml"
|
106
|
+
- ".travis.yml"
|
107
|
+
- Gemfile
|
108
|
+
- Gemfile.lock
|
109
|
+
- README.md
|
110
|
+
- Rakefile
|
111
|
+
- bin/console
|
112
|
+
- bin/rspec
|
113
|
+
- bin/rubocop
|
114
|
+
- bin/setup
|
115
|
+
- has_unique_attribute.gemspec
|
116
|
+
- lib/has_unique_attribute.rb
|
117
|
+
- lib/has_unique_attribute/version.rb
|
118
|
+
homepage: https://github.com/Mihail-K/has_unique_attribute
|
119
|
+
licenses: []
|
120
|
+
metadata:
|
121
|
+
homepage_uri: https://github.com/Mihail-K/has_unique_attribute
|
122
|
+
source_code_uri: https://github.com/Mihail-K/has_unique_attribute
|
123
|
+
post_install_message:
|
124
|
+
rdoc_options: []
|
125
|
+
require_paths:
|
126
|
+
- lib
|
127
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - ">="
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
requirements: []
|
138
|
+
rubygems_version: 3.0.3
|
139
|
+
signing_key:
|
140
|
+
specification_version: 4
|
141
|
+
summary: Handle unique attributes safely using the database.
|
142
|
+
test_files: []
|