paranoia_uniqueness_validator 1.2.0 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/dependabot.yml +13 -0
- data/.github/workflows/ci.yml +46 -0
- data/.gitignore +4 -1
- data/Gemfile +13 -31
- data/README.md +19 -13
- data/lib/paranoia_uniqueness_validator/validations/uniqueness_without_deleted.rb +16 -14
- data/lib/paranoia_uniqueness_validator/version.rb +1 -1
- data/paranoia_uniqueness_validator.gemspec +6 -5
- data/spec/dummy/.gitignore +9 -3
- data/spec/dummy/.rspec +1 -0
- data/spec/dummy/{README.rdoc → README.md} +1 -5
- data/spec/dummy/Rakefile +2 -2
- data/spec/dummy/app/assets/config/manifest.js +3 -0
- data/spec/dummy/app/{mailers → assets/images}/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +4 -4
- data/spec/dummy/app/assets/javascripts/cable.js +13 -0
- data/spec/dummy/app/{models → assets/javascripts/channels}/.keep +0 -0
- data/spec/dummy/app/assets/stylesheets/application.css +6 -4
- data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
- data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
- data/spec/dummy/app/controllers/application_controller.rb +0 -2
- data/spec/dummy/app/jobs/application_job.rb +2 -0
- data/spec/dummy/app/mailers/application_mailer.rb +4 -0
- data/spec/dummy/app/models/application_record.rb +3 -0
- data/spec/dummy/app/models/dummy_model.rb +1 -1
- data/spec/dummy/app/models/dummy_non_nil_model.rb +1 -1
- data/spec/dummy/app/views/layouts/application.html.erb +9 -9
- data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/spec/dummy/bin/rails +1 -1
- data/spec/dummy/bin/setup +34 -0
- data/spec/dummy/bin/update +29 -0
- data/spec/dummy/config.ru +2 -1
- data/spec/dummy/config/application.rb +8 -10
- data/spec/dummy/config/boot.rb +3 -5
- data/spec/dummy/config/cable.yml +9 -0
- data/spec/dummy/config/database.yml +7 -11
- data/spec/dummy/config/environment.rb +4 -4
- data/spec/dummy/config/environments/development.rb +30 -5
- data/spec/dummy/config/environments/production.rb +37 -31
- data/spec/dummy/config/environments/test.rb +10 -4
- data/spec/dummy/config/initializers/application_controller_renderer.rb +6 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/spec/dummy/config/initializers/mime_types.rb +0 -1
- data/spec/dummy/config/initializers/new_framework_defaults.rb +21 -0
- data/spec/dummy/config/initializers/session_store.rb +1 -1
- data/spec/dummy/config/initializers/wrap_parameters.rb +2 -2
- data/spec/dummy/config/puma.rb +47 -0
- data/spec/dummy/config/routes.rb +2 -48
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/config/spring.rb +6 -0
- data/spec/dummy/db/migrate/20130511080827_create_dummy_models.rb +1 -1
- data/spec/dummy/db/migrate/20160421194241_create_dummy_non_nil_models.rb +1 -1
- data/spec/dummy/db/schema.rb +5 -6
- data/spec/dummy/db/seeds.rb +3 -3
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/public/404.html +20 -11
- data/spec/dummy/public/422.html +20 -11
- data/spec/dummy/public/500.html +19 -10
- data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/spec/dummy/public/apple-touch-icon.png +0 -0
- data/spec/dummy/public/robots.txt +1 -1
- data/spec/spec_helper.rb +1 -2
- data/spec/validations/uniqueness_without_deleted_spec.rb +12 -15
- metadata +79 -32
- data/.travis.yml +0 -19
- data/spec/dummy/config/initializers/secret_token.rb +0 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d29fc508132d418f52aea5d237bcccce95c994e3fb4d16b759542aa77fffec04
|
4
|
+
data.tar.gz: ae973b381406fdf16690ea60c0dd6744ed31091f1a0a3293d15e28ffe2157b8d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d9ab8068e76c5903abc9dedce9c9d217471da093e4c5fb477c5c29ae17b9e4634519068467070a98b5c351ccd09a1f62d795bafe8545e6b410a52dae2ce127c8
|
7
|
+
data.tar.gz: fd54fb5b3e9cd372ee51ebca5fd096e766ba1b97f8342e22a7eb81000dbff6d84a4c39ae5a845251d5a54585b155526f78a2e1b6ae8f7a61f41a38539ea36b87
|
@@ -0,0 +1,46 @@
|
|
1
|
+
name: ci
|
2
|
+
|
3
|
+
on: push
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
test:
|
7
|
+
strategy:
|
8
|
+
matrix:
|
9
|
+
rails: ['6.1', '5.2']
|
10
|
+
|
11
|
+
ruby: ['2.5', '2.6', '2.7']
|
12
|
+
|
13
|
+
runs-on: ubuntu-latest
|
14
|
+
|
15
|
+
steps:
|
16
|
+
- uses: actions/checkout@v2
|
17
|
+
|
18
|
+
- uses: actions/setup-ruby@v1
|
19
|
+
|
20
|
+
with:
|
21
|
+
ruby-version: ${{ matrix.ruby }}
|
22
|
+
|
23
|
+
- name: Install native toolchain
|
24
|
+
|
25
|
+
run: |
|
26
|
+
sudo apt-get update
|
27
|
+
|
28
|
+
sudo apt-get install build-essential libsqlite3-dev
|
29
|
+
|
30
|
+
- name: Run gem install bundler
|
31
|
+
|
32
|
+
run: gem install bundler
|
33
|
+
|
34
|
+
- name: Run bundle install
|
35
|
+
|
36
|
+
env:
|
37
|
+
RAILS_VERSION: ${{ matrix.rails }}
|
38
|
+
|
39
|
+
run: bundle install
|
40
|
+
|
41
|
+
- name: Run bundle exec rspec
|
42
|
+
|
43
|
+
env:
|
44
|
+
RAILS_VERSION: ${{ matrix.rails }}
|
45
|
+
|
46
|
+
run: bundle exec rspec
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
@@ -5,41 +5,23 @@ gemspec
|
|
5
5
|
|
6
6
|
rails_version = ENV['RAILS_VERSION'] || 'default'
|
7
7
|
|
8
|
-
rails =
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
8
|
+
rails =
|
9
|
+
case rails_version
|
10
|
+
when 'master'
|
11
|
+
{ github: 'rails/rails' }
|
12
|
+
when 'default'
|
13
|
+
'>= 6.1.0'
|
14
|
+
else
|
15
|
+
"~> #{rails_version}"
|
16
|
+
end
|
16
17
|
|
17
18
|
gem 'rails', rails
|
18
19
|
|
19
|
-
platforms :jruby do
|
20
|
-
gem "activerecord-jdbcsqlite3-adapter"
|
21
|
-
gem "jruby-openssl"
|
22
|
-
end
|
23
|
-
|
24
|
-
platforms :ruby do
|
25
|
-
gem "sqlite3"
|
26
|
-
gem "test-unit"
|
27
|
-
end
|
28
|
-
|
29
|
-
platforms :ruby_19, :jruby_19 do
|
30
|
-
gem "mime-types", "< 3.0"
|
31
|
-
end
|
32
|
-
|
33
|
-
platforms :rbx do
|
34
|
-
#gem 'psych'
|
35
|
-
#gem 'racc'
|
36
|
-
#gem 'rubinius-coverage'
|
37
|
-
#gem 'rubysl'
|
38
|
-
#gem 'rubysl-test-unit'
|
39
|
-
end
|
40
|
-
|
41
20
|
group :development do
|
42
21
|
gem 'bundler'
|
43
|
-
gem 'coveralls', :
|
22
|
+
gem 'coveralls', require: false
|
23
|
+
gem 'listen'
|
44
24
|
gem 'rake'
|
25
|
+
gem 'sqlite3'
|
26
|
+
gem 'test-unit'
|
45
27
|
end
|
data/README.md
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
# ParanoiaUniquenessValidator
|
2
2
|
|
3
|
-
Adds
|
3
|
+
Adds `validates_uniqueness_without_deleted`.
|
4
4
|
|
5
|
-
This validator will ignore any record that has a non-null value for the
|
5
|
+
This validator will ignore any record that has a non-null value for the
|
6
|
+
`deleted_at` field. This gem was made specifically for use with the
|
7
|
+
[Paranoia](https://github.com/radar/paranoia) gem but it can be used with any
|
8
|
+
gem that uses the `deleted_at` field for marking records as deleted.
|
6
9
|
|
7
|
-
[![Gem Version](https://badge.fury.io/rb/paranoia_uniqueness_validator.png)](http://badge.fury.io/rb/paranoia_uniqueness_validator)
|
10
|
+
[![Gem Version](https://badge.fury.io/rb/paranoia_uniqueness_validator.png)](http://badge.fury.io/rb/paranoia_uniqueness_validator) ![ci](https://github.com/anthonator/paranoia_uniqueness_validator/workflows/ci/badge.svg) [![Coverage Status](https://coveralls.io/repos/anthonator/paranoia_uniqueness_validator/badge.png)](https://coveralls.io/r/anthonator/paranoia_uniqueness_validator) [![Code Climate](https://codeclimate.com/github/anthonator/paranoia_uniqueness_validator.png)](https://codeclimate.com/github/anthonator/paranoia_uniqueness_validator)
|
8
11
|
|
9
12
|
## Installation
|
10
13
|
|
@@ -15,6 +18,16 @@ Add this line to your application's Gemfile:
|
|
15
18
|
|
16
19
|
# Rails 4
|
17
20
|
gem 'paranoia_uniqueness_validator', '1.1.0'
|
21
|
+
|
22
|
+
# Rails 5.0
|
23
|
+
gem 'paranoia_uniqueness_validator', '2.0.0'
|
24
|
+
|
25
|
+
# Rails 5.1
|
26
|
+
gem 'paranoia_uniqueness_validator', '3.1.0'
|
27
|
+
|
28
|
+
# Rails 6
|
29
|
+
gem 'paranoia_uniqueness_validator', '3.3.0'
|
30
|
+
|
18
31
|
And then execute:
|
19
32
|
|
20
33
|
$ bundle
|
@@ -25,13 +38,14 @@ Or install it yourself as:
|
|
25
38
|
|
26
39
|
## Configuration
|
27
40
|
|
28
|
-
This validator supports all configuration options used by the base ActiveRecord
|
41
|
+
This validator supports all configuration options used by the base ActiveRecord
|
42
|
+
uniqueness validator. For more information check out the [Rails API documentation](http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#method-i-validates_uniqueness_of).
|
29
43
|
|
30
44
|
## Usage
|
31
45
|
|
32
46
|
```ruby
|
33
47
|
class SomeModel < ActiveRecord::Base
|
34
|
-
|
48
|
+
validates :some_field, uniqueness_without_deleted: true
|
35
49
|
end
|
36
50
|
```
|
37
51
|
|
@@ -42,11 +56,3 @@ end
|
|
42
56
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
43
57
|
4. Push to the branch (`git push origin my-new-feature`)
|
44
58
|
5. Create new Pull Request
|
45
|
-
|
46
|
-
## Credits
|
47
|
-
|
48
|
-
[![Sticksnleaves](http://sticksnleaves-wordpress.herokuapp.com/wp-content/themes/sticksnleaves/images/snl-logo-116x116.png)](http://www.sticksnleaves.com)
|
49
|
-
|
50
|
-
paranoia_uniqueness_validator is maintained and funded by [Sticksnleaves](http://www.sticksnleaves.com)
|
51
|
-
|
52
|
-
Thanks to all of our [contributors](https://github.com/anthonator/paranoia_uniqueness_validator/graphs/contributors)
|
@@ -3,24 +3,26 @@ module ParanoiaUniquenessValidator
|
|
3
3
|
class UniquenessWithoutDeletedValidator < ActiveRecord::Validations::UniquenessValidator
|
4
4
|
def validate_each(record, attribute, value)
|
5
5
|
finder_class = find_finder_class_for(record)
|
6
|
-
|
6
|
+
value = map_enum_attribute(finder_class, attribute, value)
|
7
|
+
|
8
|
+
relation = build_relation(finder_class, attribute, value)
|
9
|
+
if record.persisted?
|
10
|
+
if finder_class.primary_key
|
11
|
+
relation = relation.where.not(finder_class.primary_key => record.id_in_database || record.id)
|
12
|
+
else
|
13
|
+
raise UnknownPrimaryKey.new(finder_class, "Can not validate uniqueness for persisted record without primary key.")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
relation = scope_relation(record, relation)
|
17
|
+
relation = relation.merge(options[:conditions]) if options[:conditions]
|
7
18
|
|
8
|
-
if
|
9
|
-
|
19
|
+
if defined?('Paranoia') && Paranoia.respond_to?(:default_sentinel_value)
|
20
|
+
sentinel_value = Paranoia.default_sentinel_value
|
10
21
|
else
|
11
|
-
|
22
|
+
sentinel_value = nil
|
12
23
|
end
|
13
24
|
|
14
|
-
relation =
|
15
|
-
relation = relation.and(table[finder_class.primary_key.to_sym].not_eq(record.id)) if record.persisted?
|
16
|
-
|
17
|
-
default_sentinel_value = Object.const_defined?('Paranoia') ? Paranoia.default_sentinel_value : nil
|
18
|
-
|
19
|
-
relation = relation.and(table[:deleted_at].eq(default_sentinel_value))
|
20
|
-
|
21
|
-
relation = scope_relation(record, table, relation)
|
22
|
-
relation = finder_class.unscoped.where(relation)
|
23
|
-
relation = relation.merge(options[:conditions]) if options[:conditions]
|
25
|
+
relation = relation.where(deleted_at: sentinel_value)
|
24
26
|
|
25
27
|
if relation.exists?
|
26
28
|
error_options = options.except(:case_sensitive, :scope, :conditions)
|
@@ -6,20 +6,21 @@ require 'paranoia_uniqueness_validator/version'
|
|
6
6
|
Gem::Specification.new do |gem|
|
7
7
|
gem.name = "paranoia_uniqueness_validator"
|
8
8
|
gem.version = ParanoiaUniquenessValidator::VERSION
|
9
|
+
gem.licenses = ['MIT']
|
9
10
|
gem.authors = ["Anthony Smith"]
|
10
11
|
gem.email = ["anthony@sticksnleaves.com"]
|
11
12
|
gem.description = %q{Adds the validates_uniqueness_without_deleted validator to ignore deleted fields when validating for uniqueness.}
|
12
13
|
gem.summary = %q{Validate unique fields without letting those pesky deleted records get in the way. Great for use with Paranoia.}
|
13
|
-
gem.homepage = ""
|
14
|
+
gem.homepage = "https://github.com/anthonator/paranoia_uniqueness_validator"
|
14
15
|
|
15
16
|
gem.files = `git ls-files`.split($/)
|
16
17
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
18
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
19
|
gem.require_paths = ["lib"]
|
19
20
|
|
20
|
-
gem.add_dependency "activerecord", ">=
|
21
|
+
gem.add_dependency "activerecord", ">= 5.1.0", "< 6.2"
|
21
22
|
|
22
|
-
gem.add_development_dependency "paranoia"
|
23
|
-
gem.add_development_dependency "database_cleaner"
|
24
|
-
gem.add_development_dependency "rspec-rails"
|
23
|
+
gem.add_development_dependency "paranoia", "~> 2.3"
|
24
|
+
gem.add_development_dependency "database_cleaner", "~> 1.6"
|
25
|
+
gem.add_development_dependency "rspec-rails", "~> 4.0"
|
25
26
|
end
|
data/spec/dummy/.gitignore
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# See
|
1
|
+
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
|
2
2
|
#
|
3
3
|
# If you find yourself ignoring temporary files generated by your text editor
|
4
4
|
# or operating system, you probably want to add a global ignore instead:
|
@@ -8,8 +8,14 @@
|
|
8
8
|
/.bundle
|
9
9
|
|
10
10
|
# Ignore the default SQLite database.
|
11
|
+
/db/*.sqlite3
|
11
12
|
/db/*.sqlite3-journal
|
12
13
|
|
13
14
|
# Ignore all logfiles and tempfiles.
|
14
|
-
/log
|
15
|
-
/tmp
|
15
|
+
/log/*
|
16
|
+
/tmp/*
|
17
|
+
!/log/.keep
|
18
|
+
!/tmp/.keep
|
19
|
+
|
20
|
+
# Ignore Byebug command history file.
|
21
|
+
.byebug_history
|
data/spec/dummy/.rspec
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# README
|
2
2
|
|
3
3
|
This README would normally document whatever steps are necessary to get the
|
4
4
|
application up and running.
|
@@ -22,7 +22,3 @@ Things you may want to cover:
|
|
22
22
|
* Deployment instructions
|
23
23
|
|
24
24
|
* ...
|
25
|
-
|
26
|
-
|
27
|
-
Please feel free to use a different markup language if you do not plan to run
|
28
|
-
<tt>rake doc:app</tt>.
|
data/spec/dummy/Rakefile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
2
2
|
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
3
3
|
|
4
|
-
|
4
|
+
require_relative 'config/application'
|
5
5
|
|
6
|
-
|
6
|
+
Rails.application.load_tasks
|
File without changes
|
@@ -2,13 +2,13 @@
|
|
2
2
|
// listed below.
|
3
3
|
//
|
4
4
|
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
-
// or vendor/assets/javascripts
|
5
|
+
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
6
6
|
//
|
7
7
|
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
-
// compiled file.
|
8
|
+
// compiled file. JavaScript code in this file should be added after the last require_* statement.
|
9
9
|
//
|
10
|
-
//
|
11
|
-
//
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
12
|
//
|
13
13
|
//= require jquery
|
14
14
|
//= require jquery_ujs
|
@@ -0,0 +1,13 @@
|
|
1
|
+
// Action Cable provides the framework to deal with WebSockets in Rails.
|
2
|
+
// You can generate new channels where WebSocket features live using the rails generate channel command.
|
3
|
+
//
|
4
|
+
//= require action_cable
|
5
|
+
//= require_self
|
6
|
+
//= require_tree ./channels
|
7
|
+
|
8
|
+
(function() {
|
9
|
+
this.App || (this.App = {});
|
10
|
+
|
11
|
+
App.cable = ActionCable.createConsumer();
|
12
|
+
|
13
|
+
}).call(this);
|
File without changes
|
@@ -3,11 +3,13 @@
|
|
3
3
|
* listed below.
|
4
4
|
*
|
5
5
|
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
-
* or vendor/assets/stylesheets
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
7
|
*
|
8
|
-
* You're free to add application-wide styles to this file and they'll appear at the
|
9
|
-
* compiled file
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
10
12
|
*
|
11
|
-
*= require_self
|
12
13
|
*= require_tree .
|
14
|
+
*= require_self
|
13
15
|
*/
|
@@ -1,14 +1,14 @@
|
|
1
1
|
<!DOCTYPE html>
|
2
2
|
<html>
|
3
|
-
<head>
|
4
|
-
|
5
|
-
|
6
|
-
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
|
7
|
-
<%= csrf_meta_tags %>
|
8
|
-
</head>
|
9
|
-
<body>
|
3
|
+
<head>
|
4
|
+
<title>Dummy</title>
|
5
|
+
<%= csrf_meta_tags %>
|
10
6
|
|
11
|
-
<%=
|
7
|
+
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
|
8
|
+
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
|
9
|
+
</head>
|
12
10
|
|
13
|
-
|
11
|
+
<body>
|
12
|
+
<%= yield %>
|
13
|
+
</body>
|
14
14
|
</html>
|