From b02eda3fc7dde29152f252188670fa7473542876 Mon Sep 17 00:00:00 2001 From: Alfonso Uceda Date: Thu, 19 Mar 2026 09:57:47 +0100 Subject: [PATCH 01/20] Rails 8.1 support, CI is modernized - Add rails81 gemfile with activerecord ~> 8.1.0 - Add Ruby 4.0 + rails81 to CI matrix - Update postgres and mysql images to latest - Update actions/checkout to v6 - Remove redundant bundle config step --- .github/workflows/ci.yml | 11 +++++------ gemfiles/rails81.gemfile | 5 +++++ 2 files changed, 10 insertions(+), 6 deletions(-) create mode 100644 gemfiles/rails81.gemfile diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5143295..9ea9b85 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,12 +19,14 @@ jobs: gemfile: rails70 - ruby: '3.4' gemfile: rails80 + - ruby: '4.0' + gemfile: rails81 - ruby: '4.0' gemfile: railsmaster services: postgres: - image: postgres:9.6 + image: postgres env: POSTGRES_USER: root POSTGRES_DB: database_validations_test @@ -38,7 +40,7 @@ jobs: - 5432:5432 mysql: - image: mysql:5.6 + image: mysql env: MYSQL_ROOT_HOST: '%' MYSQL_ROOT_PASSWORD: test @@ -61,7 +63,7 @@ jobs: BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up Ruby uses: ruby/setup-ruby@v1 @@ -69,8 +71,5 @@ jobs: ruby-version: ${{ matrix.ruby }} bundler-cache: true - - name: Use ${{ matrix.gemfile }} as the Gemfile - run: bundle config --global gemfile ${{ matrix.gemfile }} - - name: Run tests run: bundle exec rspec diff --git a/gemfiles/rails81.gemfile b/gemfiles/rails81.gemfile new file mode 100644 index 0000000..30be048 --- /dev/null +++ b/gemfiles/rails81.gemfile @@ -0,0 +1,5 @@ +source 'https://rubygems.org' + +gem 'activerecord', '~> 8.1.0' + +gemspec path: '../' From 9fbcb56ecec7df34a5ff38a89d2e2c4107f8a60e Mon Sep 17 00:00:00 2001 From: Alfonso Uceda Date: Thu, 19 Mar 2026 09:57:52 +0100 Subject: [PATCH 02/20] Gemfile version constraints are tightened Use pessimistic version operator (~>) to pin gemfiles to their intended major.minor series instead of open-ended >= constraints. --- gemfiles/rails61.gemfile | 2 +- gemfiles/rails70.gemfile | 2 +- gemfiles/rails80.gemfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gemfiles/rails61.gemfile b/gemfiles/rails61.gemfile index 33c1f97..48206be 100644 --- a/gemfiles/rails61.gemfile +++ b/gemfiles/rails61.gemfile @@ -1,5 +1,5 @@ source 'https://rubygems.org' -gem 'activerecord', '>= 6.1' +gem 'activerecord', '~> 6.1.0' gemspec path: '../' diff --git a/gemfiles/rails70.gemfile b/gemfiles/rails70.gemfile index fa49f4f..0e0d699 100644 --- a/gemfiles/rails70.gemfile +++ b/gemfiles/rails70.gemfile @@ -1,5 +1,5 @@ source 'https://rubygems.org' -gem 'activerecord', '>= 7.0' +gem 'activerecord', '~> 7.0.0' gemspec path: '../' diff --git a/gemfiles/rails80.gemfile b/gemfiles/rails80.gemfile index d204def..2e06186 100644 --- a/gemfiles/rails80.gemfile +++ b/gemfiles/rails80.gemfile @@ -1,5 +1,5 @@ source 'https://rubygems.org' -gem 'activerecord', '>= 8.0' +gem 'activerecord', '~> 8.0.0' gemspec path: '../' From d37317aaee0c2ac13810a67e59888f2d336c40ff Mon Sep 17 00:00:00 2001 From: Alfonso Uceda Date: Thu, 19 Mar 2026 09:57:56 +0100 Subject: [PATCH 03/20] RuboCop target Ruby is updated, 2.5 to 3.3 Also adds a dedicated RuboCop CI workflow. --- .github/workflows/rubocop.yml | 28 ++++++++++++++++++++++++++++ .rubocop.yml | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/rubocop.yml diff --git a/.github/workflows/rubocop.yml b/.github/workflows/rubocop.yml new file mode 100644 index 0000000..4501fcc --- /dev/null +++ b/.github/workflows/rubocop.yml @@ -0,0 +1,28 @@ +name: Rubocop + +on: + push: + branches: [master, main] + pull_request: + +jobs: + rubocop: + runs-on: ubuntu-latest + + permissions: + contents: read + id-token: write + + + steps: + - uses: actions/checkout@v6 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + bundler-cache: true + + - name: Lint Ruby code with RuboCop + run: | + bundle exec rubocop diff --git a/.rubocop.yml b/.rubocop.yml index fc11137..14b539f 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -4,7 +4,7 @@ require: AllCops: DisplayCopNames: true - TargetRubyVersion: 2.5 + TargetRubyVersion: 3.3 Include: - '**/*.rb' - 'Gemfile' From bf726f5fd7dbeec45bf3933bca704c3c419f2a66 Mon Sep 17 00:00:00 2001 From: Alfonso Uceda Date: Thu, 19 Mar 2026 09:58:00 +0100 Subject: [PATCH 04/20] CHANGELOG trailing whitespace is removed Also resets version header to placeholder for next release. --- CHANGELOG.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1728425..5ec3349 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## [1.2.0] - 07-02-2025 +## [x.x.x] - DD-MM-YYY ### Improvements - Fix RuboCop integration. Thank to [Evgeny Matveyev](https://github.com/evgeny-matveev) for fixing it. @@ -38,7 +38,7 @@ ## [0.9.2] - 16-09-20 ### Improvements -- Fix a warning message from newest Ruby version +- Fix a warning message from newest Ruby version ## [0.9.1] - 24-06-20 ### Improvements @@ -56,14 +56,14 @@ ## [0.8.10] - 21-02-19 ### Improvements -- Internal improvements +- Internal improvements - We raise an error if `scope` or `where` options are missed for the `validates_db_uniqueness_of` ## [0.8.9] - 13-02-19 ### Bugs - Hot-fix for `validate_db_uniqueness_of` RSpec matcher -## (removed) [0.8.8] - 13-02-19 +## (removed) [0.8.8] - 13-02-19 ### Bugs - Hot-fix for `validates_db_uniqueness_of` @@ -89,7 +89,7 @@ ## [0.8.2] - 10-01-18 ### Bugs -- Fix RuboCop cop for `validates_db_uniqueness_of` to catch `validates_uniqueness_of` definition too. +- Fix RuboCop cop for `validates_db_uniqueness_of` to catch `validates_uniqueness_of` definition too. ## [0.8.1] - 09-01-18 ### Features @@ -97,7 +97,7 @@ ## [0.8.0] - 30-11-18 ### Features -- Add `db_belongs_to` +- Add `db_belongs_to` ## [0.7.3] - 2018-10-18 ### Features From 9409b6c87af42f368a0c02ccf7b65366ec75bc45 Mon Sep 17 00:00:00 2001 From: Alfonso Uceda Date: Thu, 19 Mar 2026 10:35:19 +0100 Subject: [PATCH 05/20] CodeClimate configuration is removed --- .codeclimate.yml | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 .codeclimate.yml diff --git a/.codeclimate.yml b/.codeclimate.yml deleted file mode 100644 index dc2ef1a..0000000 --- a/.codeclimate.yml +++ /dev/null @@ -1,4 +0,0 @@ -plugins: - rubocop: - enabled: true - channel: rubocop-0-64 From 4944cacde02ca9155898625a5984056a52940533 Mon Sep 17 00:00:00 2001 From: Alfonso Uceda Date: Thu, 19 Mar 2026 10:35:26 +0100 Subject: [PATCH 06/20] Gemspec version constraints are loosened --- database_validations.gemspec | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/database_validations.gemspec b/database_validations.gemspec index b49f6e5..1fd021a 100644 --- a/database_validations.gemspec +++ b/database_validations.gemspec @@ -22,14 +22,14 @@ and ActiveRecord validations with better performance and consistency." spec.add_dependency 'activerecord', '>= 4.2.0' - spec.add_development_dependency 'benchmark-ips', '~> 2.7' - spec.add_development_dependency 'bundler', '>= 2.0' - spec.add_development_dependency 'db-query-matchers', '>= 0.9' + spec.add_development_dependency 'benchmark-ips' + spec.add_development_dependency 'bundler' + spec.add_development_dependency 'db-query-matchers' spec.add_development_dependency 'mysql2' spec.add_development_dependency 'pg' - spec.add_development_dependency 'rake', '~> 13.0' - spec.add_development_dependency 'rspec', '~> 3.0' - spec.add_development_dependency 'rubocop', '~> 1.80' - spec.add_development_dependency 'rubocop-rspec', '~> 3.8' + spec.add_development_dependency 'rake' + spec.add_development_dependency 'rspec' + spec.add_development_dependency 'rubocop' + spec.add_development_dependency 'rubocop-rspec' spec.add_development_dependency 'sqlite3' end From b9fb24e29241d1ca9bea052d5a3aa8918cff5f21 Mon Sep 17 00:00:00 2001 From: Alfonso Uceda Date: Thu, 19 Mar 2026 10:35:31 +0100 Subject: [PATCH 07/20] Local development database setup docker-compose for PostgreSQL and MySQL, Rake tasks for creating and dropping test databases, and default credentials in spec_helper. --- Rakefile | 68 +++++++++++++++++++++++++++++++++++++++++++++ docker-compose.yaml | 27 ++++++++++++++++++ spec/spec_helper.rb | 8 +++--- 3 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 docker-compose.yaml diff --git a/Rakefile b/Rakefile index 4c774a2..617e680 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,74 @@ require 'bundler/gem_tasks' require 'rspec/core/rake_task' +require 'active_record' RSpec::Core::RakeTask.new(:spec) task default: :spec + +def database_configurations + configs = {} + + configs['postgresql'] = { + 'adapter' => 'postgresql', + 'database' => 'database_validations_test', + 'host' => ENV['DB_HOST'] || '127.0.0.1', + 'username' => ENV['DB_USER'] || 'database_validations', + 'password' => ENV['DB_PASSWORD'] || 'database_validations' + } + + configs['mysql'] = { + 'adapter' => 'mysql2', + 'database' => 'database_validations_test', + 'host' => ENV['DB_HOST'] || '127.0.0.1', + 'username' => ENV['MYSQL_USER'] || 'root', + 'password' => ENV['MYSQL_PASSWORD'] || 'database_validations' + } + + configs +end + +include ActiveRecord::Tasks + +DatabaseTasks.database_configuration = database_configurations +DatabaseTasks.db_dir = 'db' +DatabaseTasks.migrations_paths = [] +DatabaseTasks.root = File.dirname(__FILE__) +DatabaseTasks.env = ENV.fetch('DB', 'postgresql') + +task :environment do + ActiveRecord::Base.configurations = database_configurations + ActiveRecord::Base.establish_connection(DatabaseTasks.env.to_sym) +end + +load 'active_record/railties/databases.rake' + +namespace :db do + namespace :all do + desc 'Create both PostgreSQL and MySQL test databases' + task :create do + failures = [] + database_configurations.each do |name, config| + puts "Creating #{name} database..." + ActiveRecord::Tasks::DatabaseTasks.create(config) + rescue => e + failures << name + warn " Failed to create #{name}: #{e.message}" + end + abort "Failed to create: #{failures.join(', ')}" if failures.any? + end + + desc 'Drop both PostgreSQL and MySQL test databases' + task :drop do + failures = [] + database_configurations.each do |name, config| + puts "Dropping #{name} database..." + ActiveRecord::Tasks::DatabaseTasks.drop(config) + rescue => e + failures << name + warn " Failed to drop #{name}: #{e.message}" + end + abort "Failed to drop: #{failures.join(', ')}" if failures.any? + end + end +end diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..a255387 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,27 @@ +services: + postgresql: + container_name: "database_validations_postgresql" + image: postgres + environment: + POSTGRES_USER: database_validations + POSTGRES_PASSWORD: database_validations + POSTGRES_DB: database_validations_test + ports: + - 5432:5432 + volumes: + - pgdata:/var/lib/postgresql + + mysql: + container_name: "database_validations_mysql" + image: mysql + environment: + MYSQL_ROOT_PASSWORD: database_validations + MYSQL_DATABASE: database_validations_test + ports: + - 3306:3306 + volumes: + - mysqldata:/var/lib/mysql + +volumes: + pgdata: + mysqldata: diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 35094b8..fd218ea 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -70,8 +70,8 @@ def postgresql_configuration adapter: 'postgresql', database: 'database_validations_test', host: ENV['DB_HOST'] || '127.0.0.1', - username: ENV['DB_USER'], - password: ENV['DB_PASSWORD'] + username: ENV['DB_USER'] || 'database_validations', + password: ENV['DB_PASSWORD'] || 'database_validations' } end @@ -80,8 +80,8 @@ def mysql_configuration adapter: 'mysql2', database: 'database_validations_test', host: ENV['DB_HOST'] || '127.0.0.1', - username: ENV['DB_USER'], - password: ENV['DB_PASSWORD'] + username: ENV['DB_USER'] || 'root', + password: ENV['DB_PASSWORD'] || 'database_validations' } end From 3f37de16b13ed06cbc4b662e42836bbf7941b507 Mon Sep 17 00:00:00 2001 From: Alfonso Uceda Date: Thu, 19 Mar 2026 10:37:35 +0100 Subject: [PATCH 08/20] Development section in README is updated Docker-based setup with rake tasks is now the primary path; manual database installation is a fallback. --- README.md | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b051f24..fdf00d9 100644 --- a/README.md +++ b/README.md @@ -214,7 +214,7 @@ if you want to skip it in some cases. (For example, when you run migrations.) _N The validation has an option `:rescue` with two values: - `:default` (default option) that follows default ActiveRecord behavior. It respects `validate: false` option for `save/save!` (for example, this is being used for nested associations) -- `:always` that catches database constraint errors and turns them to ActiveRecord validations filling `.errors` properly. +- `:always` that catches database constraint errors and turns them to ActiveRecord validations filling `.errors` properly. You may want to use `rescue: :always` in case you save nested associations with `accepts_nested_attributes_for` helper and you want the validation to happen automatically when a user provides duplicated data in the same request. @@ -270,10 +270,25 @@ require: ## Development -You need to have installed and running `postgresql` and `mysql`. -And for each adapter manually create a database called `database_validations_test` accessible by your local user. +The easiest way to get started is with Docker. A `docker-compose.yaml` is +included that runs PostgreSQL and MySQL with preconfigured test databases: -Then, run `rake spec` to run the tests. +```bash +docker compose up -d +``` + +Then create the test databases and run the specs: + +```bash +rake db:all:create +rake spec +``` + +To drop the test databases: + +```bash +rake db:all:drop +``` To check the conformance with the style guides, run: From 94daa6de077a8d361cfb36907c42b1540d68c4f0 Mon Sep 17 00:00:00 2001 From: Alfonso Uceda Date: Thu, 19 Mar 2026 10:45:05 +0100 Subject: [PATCH 09/20] RuboCop configuration is modernized Target Ruby is updated to 3.4, `require` is replaced by `plugins`, new cops are disabled or excluded as needed. --- .rubocop-todo.yml | 9 ++++++++- .rubocop.yml | 17 +++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/.rubocop-todo.yml b/.rubocop-todo.yml index 0dbec72..db63557 100644 --- a/.rubocop-todo.yml +++ b/.rubocop-todo.yml @@ -1,15 +1,18 @@ -Metrics/LineLength: +Layout/LineLength: Max: 140 Exclude: - 'benchmarks/*.rb' Metrics/MethodLength: Max: 15 + Exclude: + - Rakefile Metrics/BlockLength: Exclude: - 'spec/**/*_spec.rb' - 'benchmarks/*.rb' + - Rakefile Style/Documentation: Enabled: false @@ -30,3 +33,7 @@ Style/Semicolon: Style/NumericPredicate: Exclude: - 'benchmarks/*.rb' + +Style/MixinUsage: + Exclude: + - Rakefile diff --git a/.rubocop.yml b/.rubocop.yml index 14b539f..d62a726 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,10 +1,12 @@ inherit_from: .rubocop-todo.yml -require: +plugins: - rubocop-rspec AllCops: + NewCops: disable + SuggestExtensions: false DisplayCopNames: true - TargetRubyVersion: 3.3 + TargetRubyVersion: 3.4 Include: - '**/*.rb' - 'Gemfile' @@ -24,3 +26,14 @@ Style/FrozenStringLiteralComment: RSpec/MultipleExpectations: Enabled: false + +Naming/VariableNumber: + Enabled: false + +RSpec/ExampleWording: + Enabled: false + + +Lint/ConstantDefinitionInBlock: + Exclude: + - 'benchmarks/*.rb' From b6d706de8607f83d98ca361c5d2d9bfad951cd24 Mon Sep 17 00:00:00 2001 From: Alfonso Uceda Date: Thu, 19 Mar 2026 10:45:10 +0100 Subject: [PATCH 10/20] RuboCop offenses are corrected --- Rakefile | 4 +- database_validations.gemspec | 2 +- example/config/environments/production.rb | 2 +- example/config/puma.rb | 4 +- example/db/schema.rb | 45 +++++++++---------- .../lib/checkers/db_uniqueness_validator.rb | 4 +- .../lib/validators/db_presence_validator.rb | 2 +- spec/database_validations_spec.rb | 2 +- spec/rubocop/cop/belongs_to_spec.rb | 2 +- spec/rubocop/cop/uniqueness_of_spec.rb | 2 +- .../validates_db_uniqueness_of_spec.rb | 16 +++---- 11 files changed, 42 insertions(+), 43 deletions(-) diff --git a/Rakefile b/Rakefile index 617e680..1a7cc6a 100644 --- a/Rakefile +++ b/Rakefile @@ -51,7 +51,7 @@ namespace :db do database_configurations.each do |name, config| puts "Creating #{name} database..." ActiveRecord::Tasks::DatabaseTasks.create(config) - rescue => e + rescue StandardError => e failures << name warn " Failed to create #{name}: #{e.message}" end @@ -64,7 +64,7 @@ namespace :db do database_configurations.each do |name, config| puts "Dropping #{name} database..." ActiveRecord::Tasks::DatabaseTasks.drop(config) - rescue => e + rescue StandardError => e failures << name warn " Failed to drop #{name}: #{e.message}" end diff --git a/database_validations.gemspec b/database_validations.gemspec index 1fd021a..3081f30 100644 --- a/database_validations.gemspec +++ b/database_validations.gemspec @@ -2,7 +2,7 @@ lib = File.expand_path('lib', __dir__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'database_validations/version' -Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength +Gem::Specification.new do |spec| spec.name = 'database_validations' spec.version = DatabaseValidations::VERSION spec.authors = ['Evgeniy Demin'] diff --git a/example/config/environments/production.rb b/example/config/environments/production.rb index 21f5d4e..69f124e 100644 --- a/example/config/environments/production.rb +++ b/example/config/environments/production.rb @@ -84,7 +84,7 @@ # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') if ENV['RAILS_LOG_TO_STDOUT'].present? - logger = ActiveSupport::Logger.new(STDOUT) + logger = ActiveSupport::Logger.new($stdout) logger.formatter = config.log_formatter config.logger = ActiveSupport::TaggedLogging.new(logger) end diff --git a/example/config/puma.rb b/example/config/puma.rb index f123039..7707dd9 100644 --- a/example/config/puma.rb +++ b/example/config/puma.rb @@ -4,12 +4,12 @@ # the maximum value specified for Puma. Default is set to 5 threads for minimum # and maximum; this matches the default thread size of Active Record. # -threads_count = ENV.fetch('RAILS_MAX_THREADS') { 5 } +threads_count = ENV.fetch('RAILS_MAX_THREADS', 5) threads threads_count, threads_count # Specifies the `port` that Puma will listen on to receive requests; default is 3000. # -port ENV.fetch('PORT') { 3000 } +port ENV.fetch('PORT', 3000) # Specifies the `environment` that Puma will run in. # diff --git a/example/db/schema.rb b/example/db/schema.rb index 50e3079..29881c1 100644 --- a/example/db/schema.rb +++ b/example/db/schema.rb @@ -10,35 +10,34 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2018_11_29_192039) do - +ActiveRecord::Schema.define(version: 20_181_129_192_039) do # These are extensions that must be enabled in order to support this database - enable_extension "plpgsql" + enable_extension 'plpgsql' - create_table "companies", force: :cascade do |t| - t.string "email" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + create_table 'companies', force: :cascade do |t| + t.string 'email' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false end - create_table "countries", force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + create_table 'countries', force: :cascade do |t| + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false end - create_table "users", force: :cascade do |t| - t.string "email" - t.string "full_name" - t.bigint "company_id" - t.bigint "country_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["company_id"], name: "index_users_on_company_id" - t.index ["country_id"], name: "index_users_on_country_id" - t.index ["email"], name: "index_users_on_email", unique: true - t.index ["full_name"], name: "index_users_on_full_name", unique: true + create_table 'users', force: :cascade do |t| + t.string 'email' + t.string 'full_name' + t.bigint 'company_id' + t.bigint 'country_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false + t.index ['company_id'], name: 'index_users_on_company_id' + t.index ['country_id'], name: 'index_users_on_country_id' + t.index ['email'], name: 'index_users_on_email', unique: true + t.index ['full_name'], name: 'index_users_on_full_name', unique: true end - add_foreign_key "users", "companies" - add_foreign_key "users", "countries" + add_foreign_key 'users', 'companies' + add_foreign_key 'users', 'countries' end diff --git a/lib/database_validations/lib/checkers/db_uniqueness_validator.rb b/lib/database_validations/lib/checkers/db_uniqueness_validator.rb index 4f73c6e..702002c 100644 --- a/lib/database_validations/lib/checkers/db_uniqueness_validator.rb +++ b/lib/database_validations/lib/checkers/db_uniqueness_validator.rb @@ -40,8 +40,8 @@ def validate_indexes!(klass) # rubocop:disable Metrics/AbcSize validator.attributes.map do |attribute| columns = KeyGenerator.unify_columns(attribute, validator.options[:scope]) - index = validator.index_name ? adapter.find_unique_index_by_name(validator.index_name.to_s) : adapter.find_unique_index(columns, validator.where) # rubocop:disable Metrics/LineLength - raise Errors::IndexNotFound.new(columns, validator.where, validator.index_name, adapter.unique_indexes, adapter.table_name) unless index && valid_index?(columns, index) # rubocop:disable Metrics/LineLength + index = validator.index_name ? adapter.find_unique_index_by_name(validator.index_name.to_s) : adapter.find_unique_index(columns, validator.where) # rubocop:disable Layout/LineLength + raise Errors::IndexNotFound.new(columns, validator.where, validator.index_name, adapter.unique_indexes, adapter.table_name) unless index && valid_index?(columns, index) # rubocop:disable Layout/LineLength end end end diff --git a/lib/database_validations/lib/validators/db_presence_validator.rb b/lib/database_validations/lib/validators/db_presence_validator.rb index 1d177e8..cf939c0 100644 --- a/lib/database_validations/lib/validators/db_presence_validator.rb +++ b/lib/database_validations/lib/validators/db_presence_validator.rb @@ -61,7 +61,7 @@ def db_belongs_to(name, scope = nil, **options) belongs_to(name, scope, **options) - validates_with DatabaseValidations::DbPresenceValidator, _merge_attributes([name, message: DatabaseValidations::DbPresenceValidator::REFLECTION_MESSAGE]) # rubocop:disable Metrics/LineLength + validates_with DatabaseValidations::DbPresenceValidator, _merge_attributes([name, { message: DatabaseValidations::DbPresenceValidator::REFLECTION_MESSAGE }]) # rubocop:disable Layout/LineLength end end end diff --git a/spec/database_validations_spec.rb b/spec/database_validations_spec.rb index e35cedc..20378f3 100644 --- a/spec/database_validations_spec.rb +++ b/spec/database_validations_spec.rb @@ -1,5 +1,5 @@ RSpec.describe DatabaseValidations do it 'has a version number' do - expect(DatabaseValidations::VERSION).not_to be nil + expect(DatabaseValidations::VERSION).not_to be_nil end end diff --git a/spec/rubocop/cop/belongs_to_spec.rb b/spec/rubocop/cop/belongs_to_spec.rb index f9ec262..80b824b 100644 --- a/spec/rubocop/cop/belongs_to_spec.rb +++ b/spec/rubocop/cop/belongs_to_spec.rb @@ -1,6 +1,6 @@ require 'rubocop/spec_helper' -RSpec.describe RuboCop::Cop::DatabaseValidations::BelongsTo do # rubocop:disable RSpec/FilePath +RSpec.describe RuboCop::Cop::DatabaseValidations::BelongsTo do subject(:cop) { described_class.new } it 'detects `belongs_to`: true``' do diff --git a/spec/rubocop/cop/uniqueness_of_spec.rb b/spec/rubocop/cop/uniqueness_of_spec.rb index 39d147d..a1f2d3d 100644 --- a/spec/rubocop/cop/uniqueness_of_spec.rb +++ b/spec/rubocop/cop/uniqueness_of_spec.rb @@ -1,6 +1,6 @@ require 'rubocop/spec_helper' -RSpec.describe RuboCop::Cop::DatabaseValidations::UniquenessOf do # rubocop:disable RSpec/FilePath +RSpec.describe RuboCop::Cop::DatabaseValidations::UniquenessOf do subject(:cop) { described_class.new } it 'detects `uniqueness: true`' do diff --git a/spec/validations/validates_db_uniqueness_of_spec.rb b/spec/validations/validates_db_uniqueness_of_spec.rb index cf280b8..0b13036 100644 --- a/spec/validations/validates_db_uniqueness_of_spec.rb +++ b/spec/validations/validates_db_uniqueness_of_spec.rb @@ -17,8 +17,8 @@ end it 'returns false' do - expect(db_uniqueness.new(persisted_attrs).valid?).to eq(false) - expect(app_uniqueness.new(persisted_attrs).valid?).to eq(false) + expect(db_uniqueness.new(persisted_attrs).valid?).to be(false) + expect(app_uniqueness.new(persisted_attrs).valid?).to be(false) end it 'has exactly the same errors' do @@ -233,7 +233,7 @@ def catch_error_message context 'when proc returns false' do let(:klass) do define_class do - validates_db_uniqueness_of :field, if: ->(entity) { entity.nil? } + validates_db_uniqueness_of :field, if: lambda(&:nil?) end end @@ -315,7 +315,7 @@ def catch_error_message context 'when proc returns false' do let(:klass) do define_class do - validates_db_uniqueness_of :field, unless: ->(entity) { entity.nil? } + validates_db_uniqueness_of :field, unless: lambda(&:nil?) end end @@ -390,8 +390,8 @@ def catch_error_message nil end expect(parent_class.count).to eq(0) - expect(new.persisted?).to eq(false) - expect(old.persisted?).to eq(false) + expect(new.persisted?).to be(false) + expect(old.persisted?).to be(false) end end @@ -715,8 +715,8 @@ def catch_error_message describe '#valid?' do it 'works' do - expect(db_uniqueness.new(persisted_attrs).valid?).to eq(true) - expect(app_uniqueness.new(persisted_attrs).valid?).to eq(true) + expect(db_uniqueness.new(persisted_attrs).valid?).to be(true) + expect(app_uniqueness.new(persisted_attrs).valid?).to be(true) end end From 25a235b934534e4c955c211680efa71798b92470 Mon Sep 17 00:00:00 2001 From: Alfonso Uceda Date: Thu, 19 Mar 2026 11:00:44 +0100 Subject: [PATCH 11/20] Minimum Ruby version is set to 3.0 --- .rubocop.yml | 2 +- database_validations.gemspec | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.rubocop.yml b/.rubocop.yml index d62a726..6e40760 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -6,7 +6,7 @@ AllCops: NewCops: disable SuggestExtensions: false DisplayCopNames: true - TargetRubyVersion: 3.4 + TargetRubyVersion: 3.0 Include: - '**/*.rb' - 'Gemfile' diff --git a/database_validations.gemspec b/database_validations.gemspec index 3081f30..4a5bd5b 100644 --- a/database_validations.gemspec +++ b/database_validations.gemspec @@ -19,6 +19,7 @@ and ActiveRecord validations with better performance and consistency." spec.license = 'MIT' spec.files = Dir['lib/**/*'] spec.require_paths = ['lib'] + spec.required_ruby_version = '>= 3.0.0' spec.add_dependency 'activerecord', '>= 4.2.0' From 33eead0c9a31ca703a0cf08409b79e0f9485bde7 Mon Sep 17 00:00:00 2001 From: Alfonso Uceda Date: Thu, 19 Mar 2026 11:00:47 +0100 Subject: [PATCH 12/20] RuboCop offenses in specs are addressed --- .rubocop-todo.yml | 4 ++++ spec/spec_helper.rb | 6 +++++- spec/validations/db_belongs_to_spec.rb | 12 ++++++++---- spec/validations/validates_db_uniqueness_of_spec.rb | 6 +++--- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/.rubocop-todo.yml b/.rubocop-todo.yml index db63557..c0e1f14 100644 --- a/.rubocop-todo.yml +++ b/.rubocop-todo.yml @@ -37,3 +37,7 @@ Style/NumericPredicate: Style/MixinUsage: Exclude: - Rakefile + +RSpec/SpecFilePathFormat: + Exclude: + - spec/rubocop/**/*.rb diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index fd218ea..843444f 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -49,8 +49,12 @@ def define_class(parent = ActiveRecord::Base, table_name = :entities, &block) Class.new(parent) do |klass| self.table_name = table_name + def self.name + 'Temp' + end + def self.model_name - ActiveModel::Name.new(self, nil, 'temp') + ActiveModel::Name.new(self, nil, 'Temp') end reset_column_information diff --git a/spec/validations/db_belongs_to_spec.rb b/spec/validations/db_belongs_to_spec.rb index c5deaa1..2f3672b 100644 --- a/spec/validations/db_belongs_to_spec.rb +++ b/spec/validations/db_belongs_to_spec.rb @@ -1,7 +1,11 @@ RSpec.describe 'db_belongs_to' do - class Company < ActiveRecord::Base; end # rubocop:disable RSpec/LeakyConstantDeclaration - class BelongsUser < ActiveRecord::Base; end # rubocop:disable RSpec/LeakyConstantDeclaration - class DbBelongsUser < ActiveRecord::Base; end # rubocop:disable RSpec/LeakyConstantDeclaration + # rubocop:disable RSpec/LeakyConstantDeclaration + # rubocop:disable Lint/ConstantDefinitionInBlock + class Company < ActiveRecord::Base; end + class BelongsUser < ActiveRecord::Base; end + class DbBelongsUser < ActiveRecord::Base; end + # rubocop:enable RSpec/LeakyConstantDeclaration + # rubocop:enable Lint/ConstantDefinitionInBlock let(:company_klass) { define_class(Company, :companies) } @@ -59,7 +63,7 @@ def define_tables shared_examples 'works as belongs_to' do shared_examples 'with company_id provided' do |method, field, company_id| - context "#{method} on #{field} with #{company_id.inspect}" do + context "when '#{method}' on '#{field}' with '#{company_id.inspect}'" do specify do # Hack validate_db_queries = !(method == :valid? && [:existing_id, -1].include?(company_id)) diff --git a/spec/validations/validates_db_uniqueness_of_spec.rb b/spec/validations/validates_db_uniqueness_of_spec.rb index 0b13036..56291fb 100644 --- a/spec/validations/validates_db_uniqueness_of_spec.rb +++ b/spec/validations/validates_db_uniqueness_of_spec.rb @@ -466,13 +466,13 @@ def catch_error_message it_behaves_like 'ActiveRecord::Validation' - context do + context do # rubocop:disable RSpec/MissingExampleGroupArgument define_negated_matcher :not_change, :change before { parent_class.create!(persisted_attrs) } it "doesn't rescue from the constraint violation" do - expect_any_instance_of(ActiveRecord::Validations::UniquenessValidator) + expect_any_instance_of(ActiveRecord::Validations::UniquenessValidator) # rubocop:disable RSpec/AnyInstance .to receive(:scope_relation).twice.and_return(RAILS_5 ? app_uniqueness.none : '1=0') expect { app_uniqueness.create(persisted_attrs) } @@ -502,7 +502,7 @@ def catch_error_message it_behaves_like 'ActiveRecord::Validation' end - context 'when parent class set validation of flow' do + context 'when parent class set validation of flow' do # rubocop:disable RSpec/MultipleMemoizedHelpers before do define_table do |t| t.string :field From b99773fde7675ae8e2d3cbf5bc53193581c2b395 Mon Sep 17 00:00:00 2001 From: Alfonso Uceda Date: Thu, 19 Mar 2026 11:28:04 +0100 Subject: [PATCH 13/20] Database configuration is consolidated into config/database.yml Credentials were duplicated across docker-compose.yaml, Rakefile, and spec_helper.rb with inconsistent env var names (MYSQL_USER vs DB_USER). A shared DatabaseConfig module now loads a single YAML file for both the Rakefile and specs. The sqlite adapter is also skipped in db:all:create and db:all:drop tasks where it was incorrectly included. --- Rakefile | 35 ++++++++++------------------------- config/database.yml | 17 +++++++++++++++++ config/database_config.rb | 12 ++++++++++++ spec/spec_helper.rb | 24 ++++++------------------ 4 files changed, 45 insertions(+), 43 deletions(-) create mode 100644 config/database.yml create mode 100644 config/database_config.rb diff --git a/Rakefile b/Rakefile index 1a7cc6a..64a5939 100644 --- a/Rakefile +++ b/Rakefile @@ -1,43 +1,24 @@ require 'bundler/gem_tasks' require 'rspec/core/rake_task' require 'active_record' +require_relative 'config/database_config' RSpec::Core::RakeTask.new(:spec) task default: :spec -def database_configurations - configs = {} - - configs['postgresql'] = { - 'adapter' => 'postgresql', - 'database' => 'database_validations_test', - 'host' => ENV['DB_HOST'] || '127.0.0.1', - 'username' => ENV['DB_USER'] || 'database_validations', - 'password' => ENV['DB_PASSWORD'] || 'database_validations' - } - - configs['mysql'] = { - 'adapter' => 'mysql2', - 'database' => 'database_validations_test', - 'host' => ENV['DB_HOST'] || '127.0.0.1', - 'username' => ENV['MYSQL_USER'] || 'root', - 'password' => ENV['MYSQL_PASSWORD'] || 'database_validations' - } - - configs -end +DATABASE_CONFIGURATIONS = DatabaseConfig.load include ActiveRecord::Tasks -DatabaseTasks.database_configuration = database_configurations +DatabaseTasks.database_configuration = DATABASE_CONFIGURATIONS DatabaseTasks.db_dir = 'db' DatabaseTasks.migrations_paths = [] DatabaseTasks.root = File.dirname(__FILE__) DatabaseTasks.env = ENV.fetch('DB', 'postgresql') task :environment do - ActiveRecord::Base.configurations = database_configurations + ActiveRecord::Base.configurations = DATABASE_CONFIGURATIONS ActiveRecord::Base.establish_connection(DatabaseTasks.env.to_sym) end @@ -48,7 +29,9 @@ namespace :db do desc 'Create both PostgreSQL and MySQL test databases' task :create do failures = [] - database_configurations.each do |name, config| + DATABASE_CONFIGURATIONS.each do |name, config| + next if config['adapter'] == 'sqlite3' + puts "Creating #{name} database..." ActiveRecord::Tasks::DatabaseTasks.create(config) rescue StandardError => e @@ -61,7 +44,9 @@ namespace :db do desc 'Drop both PostgreSQL and MySQL test databases' task :drop do failures = [] - database_configurations.each do |name, config| + DATABASE_CONFIGURATIONS.each do |name, config| + next if config['adapter'] == 'sqlite3' + puts "Dropping #{name} database..." ActiveRecord::Tasks::DatabaseTasks.drop(config) rescue StandardError => e diff --git a/config/database.yml b/config/database.yml new file mode 100644 index 0000000..bb258bb --- /dev/null +++ b/config/database.yml @@ -0,0 +1,17 @@ +postgresql: + adapter: postgresql + database: database_validations_test + host: <%= ENV['DB_HOST'] || '127.0.0.1' %> + username: <%= ENV['DB_USER'] || 'database_validations' %> + password: <%= ENV['DB_PASSWORD'] || 'database_validations' %> + +mysql: + adapter: mysql2 + database: database_validations_test + host: <%= ENV['DB_HOST'] || '127.0.0.1' %> + username: <%= ENV['DB_USER'] || 'root' %> + password: <%= ENV['DB_PASSWORD'] || 'database_validations' %> + +sqlite: + adapter: sqlite3 + database: ':memory:' diff --git a/config/database_config.rb b/config/database_config.rb new file mode 100644 index 0000000..fb0715e --- /dev/null +++ b/config/database_config.rb @@ -0,0 +1,12 @@ +require 'erb' +require 'yaml' + +module DatabaseConfig + def self.load(symbolize_keys: false) + yaml_path = File.expand_path('database.yml', __dir__) + yaml_content = ERB.new(File.read(yaml_path)).result + configs = YAML.safe_load(yaml_content) + configs = configs.transform_values { |v| v.transform_keys(&:to_sym) } if symbolize_keys + configs + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 843444f..43975ac 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -2,6 +2,7 @@ require 'database_validations' require 'shared/raise_index_not_found' require 'db-query-matchers' +require_relative '../config/database_config' # Use this constant to enable Rails 5+ compatible specs RAILS_5 = ActiveRecord::VERSION::MAJOR >= 5 @@ -69,29 +70,16 @@ def rescue_error e.message end +DATABASE_CONFIGURATIONS = DatabaseConfig.load(symbolize_keys: true) + def postgresql_configuration - { - adapter: 'postgresql', - database: 'database_validations_test', - host: ENV['DB_HOST'] || '127.0.0.1', - username: ENV['DB_USER'] || 'database_validations', - password: ENV['DB_PASSWORD'] || 'database_validations' - } + DATABASE_CONFIGURATIONS['postgresql'] end def mysql_configuration - { - adapter: 'mysql2', - database: 'database_validations_test', - host: ENV['DB_HOST'] || '127.0.0.1', - username: ENV['DB_USER'] || 'root', - password: ENV['DB_PASSWORD'] || 'database_validations' - } + DATABASE_CONFIGURATIONS['mysql'] end def sqlite_configuration - { - adapter: 'sqlite3', - database: ':memory:' - } + DATABASE_CONFIGURATIONS['sqlite'] end From 67b176a552a1e95a1f86b4cda58f00b131196f7b Mon Sep 17 00:00:00 2001 From: Alfonso Uceda Date: Thu, 19 Mar 2026 11:30:58 +0100 Subject: [PATCH 14/20] CHANGELOG is updated with meaningful changes from this branch --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ec3349..9051f58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ ## [x.x.x] - DD-MM-YYY ### Improvements +- Add Rails 8.1 support +- Set minimum Ruby version to 3.0 +- Loosen gemspec development dependency version constraints +- Modernize CI configuration and add dedicated RuboCop workflow +- Consolidate database configuration into `config/database.yml` +- Add local development database setup with Docker Compose - Fix RuboCop integration. Thank to [Evgeny Matveyev](https://github.com/evgeny-matveev) for fixing it. ## [1.1.1] - 14-03-2022 From 60a3eaef74f43f2ed66088cae00b2af3de5a322e Mon Sep 17 00:00:00 2001 From: Alfonso Uceda Date: Thu, 19 Mar 2026 11:31:22 +0100 Subject: [PATCH 15/20] .ruby-version is tracked Ensures consistent Ruby version across development environments. --- .gitignore | 1 - .ruby-version | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 .ruby-version diff --git a/.gitignore b/.gitignore index 3fbb65f..dd63538 100644 --- a/.gitignore +++ b/.gitignore @@ -22,5 +22,4 @@ example/log example/Gemfile.lock example/config/database.yml -.ruby-version .ruby-gemset diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..2f4b607 --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +3.4 From 959105a1c4a4d248754b4132bf72746058a5d133 Mon Sep 17 00:00:00 2001 From: Alfonso Uceda Date: Thu, 19 Mar 2026 11:31:52 +0100 Subject: [PATCH 16/20] CI matrix fail-fast is disabled Allows all combinations to complete even when one fails, giving better visibility into which environments are broken. --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9ea9b85..63d36f8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,6 +11,8 @@ jobs: runs-on: ubuntu-latest strategy: + fail-fast: false + matrix: include: - ruby: '2.7' From dab618b10481f457b5310137212f9b65c7ba9fb7 Mon Sep 17 00:00:00 2001 From: Alfonso Uceda Date: Thu, 19 Mar 2026 11:38:01 +0100 Subject: [PATCH 17/20] Rails 6.1 support is removed Minimum activerecord dependency is raised to 7.0. The Rails 6.1 gemfile and its CI matrix entry are removed accordingly. --- .github/workflows/ci.yml | 3 +-- database_validations.gemspec | 2 +- gemfiles/rails61.gemfile | 5 ----- 3 files changed, 2 insertions(+), 8 deletions(-) delete mode 100644 gemfiles/rails61.gemfile diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 63d36f8..0e0e8df 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,8 +15,6 @@ jobs: matrix: include: - - ruby: '2.7' - gemfile: rails61 - ruby: '3.0' gemfile: rails70 - ruby: '3.4' @@ -72,6 +70,7 @@ jobs: with: ruby-version: ${{ matrix.ruby }} bundler-cache: true + bundler: latest - name: Run tests run: bundle exec rspec diff --git a/database_validations.gemspec b/database_validations.gemspec index 4a5bd5b..634dcf9 100644 --- a/database_validations.gemspec +++ b/database_validations.gemspec @@ -21,7 +21,7 @@ and ActiveRecord validations with better performance and consistency." spec.require_paths = ['lib'] spec.required_ruby_version = '>= 3.0.0' - spec.add_dependency 'activerecord', '>= 4.2.0' + spec.add_dependency 'activerecord', '>= 7.0.0' spec.add_development_dependency 'benchmark-ips' spec.add_development_dependency 'bundler' diff --git a/gemfiles/rails61.gemfile b/gemfiles/rails61.gemfile deleted file mode 100644 index 48206be..0000000 --- a/gemfiles/rails61.gemfile +++ /dev/null @@ -1,5 +0,0 @@ -source 'https://rubygems.org' - -gem 'activerecord', '~> 6.1.0' - -gemspec path: '../' From a66fb9617680f48999f66beaad7b000cee722d1b Mon Sep 17 00:00:00 2001 From: Alfonso Uceda Date: Thu, 19 Mar 2026 11:41:00 +0100 Subject: [PATCH 18/20] sqlite3 version is pinned for Rails 7.0 gemfile Rails 7.0 requires sqlite3 ~> 1.4; newer versions are incompatible. --- gemfiles/rails70.gemfile | 1 + 1 file changed, 1 insertion(+) diff --git a/gemfiles/rails70.gemfile b/gemfiles/rails70.gemfile index 0e0d699..cc15713 100644 --- a/gemfiles/rails70.gemfile +++ b/gemfiles/rails70.gemfile @@ -1,5 +1,6 @@ source 'https://rubygems.org' gem 'activerecord', '~> 7.0.0' +gem 'sqlite3', '~> 1.4' gemspec path: '../' From 78a2243104fade56537afb43640d9594556c1c9a Mon Sep 17 00:00:00 2001 From: Alfonso Uceda Date: Thu, 19 Mar 2026 11:45:03 +0100 Subject: [PATCH 19/20] lambda(&:nil?) in specs is replaced with explicit lambdas Rails 7.0 evaluates :if/:unless callback conditions via instance_exec, which doesn't pass the instance as an argument to Symbol#to_proc lambdas, causing "no receiver given" errors. --- spec/validations/validates_db_uniqueness_of_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/validations/validates_db_uniqueness_of_spec.rb b/spec/validations/validates_db_uniqueness_of_spec.rb index 56291fb..f0316d2 100644 --- a/spec/validations/validates_db_uniqueness_of_spec.rb +++ b/spec/validations/validates_db_uniqueness_of_spec.rb @@ -233,7 +233,7 @@ def catch_error_message context 'when proc returns false' do let(:klass) do define_class do - validates_db_uniqueness_of :field, if: lambda(&:nil?) + validates_db_uniqueness_of :field, if: ->(entity) { entity.nil? } # rubocop:disable Style/SymbolProc end end @@ -315,7 +315,7 @@ def catch_error_message context 'when proc returns false' do let(:klass) do define_class do - validates_db_uniqueness_of :field, unless: lambda(&:nil?) + validates_db_uniqueness_of :field, unless: ->(entity) { entity.nil? } # rubocop:disable Style/SymbolProc end end From 5e4946c2e603df50f626245cd247a344710f6a87 Mon Sep 17 00:00:00 2001 From: Alfonso Uceda Date: Fri, 20 Mar 2026 09:47:48 +0100 Subject: [PATCH 20/20] Explicit ruby-version in RuboCop workflow is removed setup-ruby reads from .ruby-version by default; the matrix variable was redundant. --- .github/workflows/rubocop.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/rubocop.yml b/.github/workflows/rubocop.yml index 4501fcc..a48588c 100644 --- a/.github/workflows/rubocop.yml +++ b/.github/workflows/rubocop.yml @@ -13,14 +13,12 @@ jobs: contents: read id-token: write - steps: - uses: actions/checkout@v6 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: ${{ matrix.ruby }} bundler-cache: true - name: Lint Ruby code with RuboCop