Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: An error occurred while Rails/UniqueValidationWithoutIndex cop was inspecting <file> (uniqueness: in validation) #318

Closed
rylanb opened this issue Aug 4, 2020 · 11 comments

Comments

@rylanb
Copy link

rylanb commented Aug 4, 2020

Information

I think this is a bug, but I'm not 100% sure on that. Instead of getting a 'todo fix' for the Rubocop run, the run 'passes' and tells me that it passed but Rubocop errorred. It fails on Github Actions, however.

Similar issue: #226 perhaps?

I'm happy to provide any more information that would be useful here. I'll also go back and poke at adding the indexes again, maybe I messed something up in my first try there.


Expected behavior

Rubocop tells me that there is a unique ActiveRecord validation / schema.rb mismatch on indexes and I need to add a unique index based on a scoped ActiveRecord validation.

I believe this might be related to uniqueness: { case_sensitive: false } or uniqueness: { scope: :state_id, case_sensitive: false } validations in AR.

Actual behavior

I get the following output during a full bundle exec rubocop run:

1726 files inspected, no offenses detected

3 errors occurred:
An error occurred while Rails/UniqueValidationWithoutIndex cop was inspecting /app/models/county.rb:5:2.
An error occurred while Rails/UniqueValidationWithoutIndex cop was inspecting /app/models/state.rb:16:2.
An error occurred while Rails/UniqueValidationWithoutIndex cop was inspecting /app/models/state.rb:17:2.

Errors are usually caused by RuboCop bugs.
Please, report your problems to RuboCop's issue tracker.
https://github.com/rubocop-hq/rubocop/issues

Mention the following information in the issue report:
0.73.0 (using Parser 2.7.1.4, running on ruby 2.5.7 x86_64-darwin17)

Every model that is failing (I get 12 total) have some use of uniqueness: as their common trait.

Examples:
validates :email, presence: true, uniqueness: true
validates :short_name, uniqueness: { case_sensitive: false }, presence: true
validates :email, uniqueness: true
validates :name, uniqueness: true
validates :carrier_id, uniqueness: { scope: :user_id }
validates :quote_person, presence: true, uniqueness: { message: 'already has a spouse' }

Output running -d command:

rubocop -d app/models/county.rb

https://gist.github.com/rylanb/a7fc2786018ba736c8b15837f1a03950

Steps to reproduce the problem

county.rb

class County < ApplicationRecord
  belongs_to :state
  has_many :zipcodes

  validates :name, uniqueness: { scope: :state_id, case_sensitive: false }, presence: true
  validate :validate_name
  ...
end

Relevant schema.rb

create_table "counties", id: :serial, force: :cascade do |t|
    t.integer "state_id"
    t.string "abbr"
    t.string "name"
    t.string "county_seat"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.index ["name"], name: "index_counties_on_name"
    t.index ["state_id"], name: "index_counties_on_state_id" 
  end

( I think the index index_counties_on_state_id needs updating, but if I update to add one, it doesn't seem to change the error)

Edit: I tried by adding this unique index to Counties:

class AddUniqueIndexToStateIdOnCounty < ActiveRecord::Migration[5.2]
  def change
    remove_index :counties, :state_id
    add_index :counties, [:name, :state_id], unique: true
  end
end

So, either its the case sensitivity in there or something around the scope: { } or the case_sensitive in the scope block.

bundle exec rubocop -d app/models/county.rb:

An error occurred while Rails/UniqueValidationWithoutIndex cop was inspecting /Users/rylanbowers/Dev/Freelance/Ill-Corporation/BeneFix/benefix-quoting/app/models/county.rb:5:2.
undefined method `method?' for #<RuboCop::AST::BlockNode:0x00007f91aded5e90>
Did you mean?  method
               methods

state.rb

class State < ApplicationRecord
  validates :short_name, uniqueness: { case_sensitive: false }, presence: true (line 16)
  validates :name, uniqueness: { case_sensitive: false }, presence: true (line 17)
end

Relevant schema.rb


create_table "states", id: :serial, force: :cascade do |t|
    t.string "name", null: false
    t.string "short_name", limit: 2, null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.boolean "is_live", default: true
    t.index ["name"], name: "index_states_on_name", unique: true
    t.index ["short_name"], name: "index_states_on_short_name"
  end

RuboCop version

$ [bundle exec] rubocop -V
0.73.0 (using Parser 2.7.1.4, running on ruby 2.5.7 x86_64-darwin17)

.rubocop.yml

require: [rubocop-rspec, rubocop-rails]
inherit_from: .rubocop_todo.yml

AllCops:
  TargetRailsVersion: 5.2.0
  TargetRubyVersion: 2.5.7
@rylanb rylanb changed the title BUG: An error occurred while Rails/UniqueValidationWithoutIndex cop was inspecting <file> BUG: An error occurred while Rails/UniqueValidationWithoutIndex cop was inspecting <file> (uniqueness: in validation) Aug 4, 2020
@rylanb
Copy link
Author

rylanb commented Aug 18, 2020

@koic any chance you've had time to look at this? Thanks in advance! I know OSS is tough and I appreciate any insight you can give!

@koic
Copy link
Member

koic commented Aug 21, 2020

Thank you for opening the issue. It may take some time because I have not yet been able to reproduce the issue locally.

@rylanb
Copy link
Author

rylanb commented Aug 22, 2020

@koic no problem! I fully understand that one. Its busy on my end, too. I'll try to poke at it more on my end, could always be user error!

@AndrewHYi
Copy link

@rylanb Looks like there's a problem with rubocop/rubocop-rails versions. RuboCop::AST::BlockNode#method? (which just delegates to #send_node...) was added in rubocop v. 0.77.0 (gemspec has a minimum dependency version of 0.72.0, but it's wrong see: #197), so try upgrading that.

It's not in the release notes for 0.77.0 unfortunately, but here is the commit:

rubocop/rubocop@a2b67db#diff-dca43f66b47f1f1c06c2c5e987d12b30R12

@rylanb
Copy link
Author

rylanb commented Aug 25, 2020

@AndrewHYi bless you 🙏

I hadn't realized I'd set a hard version w/ ~0.770 in my Gemfile, so rubocop wasn't updating! Thank you so much! That fixed it.

For anyone coming along that may see this

I had

gem 'rubocop', '~> 0.77.0', require: false

so bundle update rubocop and apparently dependabot, as well, won't update when you do that 3rd patch set at .0. Been awhile since I looked at that!

Fix
gem 'rubocop', '~> 0.77', require: false

and then bundle update rubocop

Fixed

@rylanb rylanb closed this as completed Aug 25, 2020
@eneagoe
Copy link

eneagoe commented Sep 15, 2020

Is it possible that 2.8.0 introduced a regression?

We have a class which passes the checks on 2.7.1, but with 2.8.0 it fails:

Scanning [...]/app/models/committees/committee_member_role.rb
An error occurred while Rails/UniqueValidationWithoutIndex cop was inspecting [...]app/models/committees/committee_member_role.rb:59:4.
undefined method `with_column?' for nil:NilClass
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-rails-2.8.0/lib/rubocop/cop/mixin/active_record_helper.rb:55:in `resolve_relation_into_column'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-rails-2.8.0/lib/rubocop/cop/rails/unique_validation_without_index.rb:84:in `block in column_names'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-rails-2.8.0/lib/rubocop/cop/rails/unique_validation_without_index.rb:82:in `map!'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-rails-2.8.0/lib/rubocop/cop/rails/unique_validation_without_index.rb:82:in `column_names'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-rails-2.8.0/lib/rubocop/cop/rails/unique_validation_without_index.rb:50:in `find_schema_information'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-rails-2.8.0/lib/rubocop/cop/rails/unique_validation_without_index.rb:38:in `on_send'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/cop/commissioner.rb:99:in `block (2 levels) in trigger_responding_cops'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/cop/commissioner.rb:152:in `with_cop_error_handling'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/cop/commissioner.rb:98:in `block in trigger_responding_cops'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/cop/commissioner.rb:97:in `each'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/cop/commissioner.rb:97:in `trigger_responding_cops'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/cop/commissioner.rb:70:in `on_send'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-ast-0.4.0/lib/rubocop/ast/traversal.rb:59:in `block in on_begin'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-ast-0.4.0/lib/rubocop/ast/traversal.rb:59:in `each'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-ast-0.4.0/lib/rubocop/ast/traversal.rb:59:in `on_begin'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/cop/commissioner.rb:72:in `on_begin'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-ast-0.4.0/lib/rubocop/ast/traversal.rb:101:in `on_class'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/cop/commissioner.rb:72:in `on_class'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-ast-0.4.0/lib/rubocop/ast/traversal.rb:159:in `on_while'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/cop/commissioner.rb:72:in `on_module'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-ast-0.4.0/lib/rubocop/ast/traversal.rb:14:in `walk'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/cop/commissioner.rb:85:in `investigate'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/cop/team.rb:152:in `investigate_partial'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/cop/team.rb:83:in `investigate'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/runner.rb:311:in `inspect_file'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/runner.rb:255:in `block in do_inspection_loop'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/runner.rb:289:in `block in iterate_until_no_changes'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/runner.rb:282:in `loop'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/runner.rb:282:in `iterate_until_no_changes'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/runner.rb:251:in `do_inspection_loop'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/runner.rb:128:in `block in file_offenses'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/runner.rb:153:in `file_offense_cache'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/runner.rb:127:in `file_offenses'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/runner.rb:118:in `process_file'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/runner.rb:97:in `block in each_inspected_file'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/runner.rb:96:in `each'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/runner.rb:96:in `reduce'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/runner.rb:96:in `each_inspected_file'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/runner.rb:82:in `inspect_files'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/runner.rb:43:in `run'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/cli/command/execute_runner.rb:25:in `execute_runner'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/cli/command/execute_runner.rb:17:in `run'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/cli/command.rb:11:in `run'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/cli/environment.rb:18:in `run'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/cli.rb:65:in `run_command'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/cli.rb:72:in `execute_runners'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/lib/rubocop/cli.rb:41:in `run'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/exe/rubocop:13:in `block in <top (required)>'
/Users/eneagoe/.rvm/rubies/ruby-2.7.1/lib/ruby/2.7.0/benchmark.rb:308:in `realtime'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/gems/rubocop-0.91.0/exe/rubocop:12:in `<top (required)>'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/bin/rubocop:23:in `load'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/bin/rubocop:23:in `<main>'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/bin/ruby_executable_hooks:24:in `eval'
/Users/eneagoe/.rvm/gems/ruby-2.7.1@corpware-webapp/bin/ruby_executable_hooks:24:in `<main>'
.

1 file inspected, no offenses detected

1 error occurred:
An error occurred while Rails/UniqueValidationWithoutIndex cop was inspecting [...]app/models/committees/committee_member_role.rb:59:4.
Errors are usually caused by RuboCop bugs.
Please, report your problems to RuboCop's issue tracker.
https://github.com/rubocop-hq/rubocop/issues

Mention the following information in the issue report:
0.91.0 (using Parser 2.7.1.4, rubocop-ast 0.4.0, running on ruby 2.7.1 x86_64-darwin19)

The relevant code for the checked class is:

module Committees
  class CommitteeMemberRole < ApplicationRecord
     validates :name, uniqueness: {scope: [:customer_id, :committee],
                                 message: proc { |_, attributes| I18n.t("has_already_been_taken", name: attributes[:value]) }}

  end
end

If we add self.table_name = "committee_member_roles" to the class definition, there's no error, but this seems a bit redundant.

@andyw8
Copy link
Contributor

andyw8 commented Sep 15, 2020

@eneagoe Please open a new issue for this.

@plribeiro3000
Copy link

Version 2.20.1 introduced a regression on this.
Everything works fine on version 2.19.1 but fails with this error when updating to 2.20.1.

Should we follow here since is a regression or do i open a new issue?

@koic
Copy link
Member

koic commented Jun 19, 2023

RuboCop Rails 2.20.2 has just been released now. Can you upgrade to the latest version?

@plribeiro3000
Copy link

Sure. Let me try!

@plribeiro3000
Copy link

Problem solved! Thanks a bunch! ❤️ 💚 💙 💜 💛 🧡

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants