diff --git a/lib/rubocop/cop/rails/duplicate_association.rb b/lib/rubocop/cop/rails/duplicate_association.rb index 3c1da3ec07..cec9c00e64 100644 --- a/lib/rubocop/cop/rails/duplicate_association.rb +++ b/lib/rubocop/cop/rails/duplicate_association.rb @@ -35,7 +35,7 @@ def on_class(class_node) offenses(class_node).each do |name, nodes| nodes.each do |node| add_offense(node, message: format(MSG, name: name)) do |corrector| - next if nodes.last == node + next if same_line?(nodes.last, node) corrector.remove(range_by_whole_lines(node.source_range, include_final_newline: true)) end diff --git a/spec/rubocop/cop/rails/duplicate_association_spec.rb b/spec/rubocop/cop/rails/duplicate_association_spec.rb index cf128c60de..43d9e0c3cf 100644 --- a/spec/rubocop/cop/rails/duplicate_association_spec.rb +++ b/spec/rubocop/cop/rails/duplicate_association_spec.rb @@ -3,6 +3,27 @@ RSpec.describe RuboCop::Cop::Rails::DuplicateAssociation, :config do describe 'belongs_to' do it 'registers an offense' do + expect_offense(<<~RUBY) + class Post < ApplicationRecord + belongs_to :foo + ^^^^^^^^^^^^^^^ Association `foo` is defined multiple times. Don't repeat associations. + belongs_to :bar + belongs_to :foo + ^^^^^^^^^^^^^^^ Association `foo` is defined multiple times. Don't repeat associations. + belongs_to :blah + end + RUBY + + expect_correction(<<~RUBY) + class Post < ApplicationRecord + belongs_to :bar + belongs_to :foo + belongs_to :blah + end + RUBY + end + + it 'registers an offense with scope block' do expect_offense(<<~RUBY) class Post < ApplicationRecord belongs_to :foo @@ -26,6 +47,27 @@ class Post < ApplicationRecord describe 'has_many' do it 'registers an offense' do + expect_offense(<<~RUBY) + class Post < ApplicationRecord + has_many :foos + ^^^^^^^^^^^^^^ Association `foos` is defined multiple times. Don't repeat associations. + has_many :bars + has_many :foos + ^^^^^^^^^^^^^^ Association `foos` is defined multiple times. Don't repeat associations. + has_many :blahs + end + RUBY + + expect_correction(<<~RUBY) + class Post < ApplicationRecord + has_many :bars + has_many :foos + has_many :blahs + end + RUBY + end + + it 'registers an offense with scope block' do expect_offense(<<~RUBY) class Post < ApplicationRecord has_many :foos @@ -49,6 +91,27 @@ class Post < ApplicationRecord describe 'has_one' do it 'registers an offense' do + expect_offense(<<~RUBY) + class Post < ApplicationRecord + has_one :foo + ^^^^^^^^^^^^ Association `foo` is defined multiple times. Don't repeat associations. + has_one :bar + has_one :foo + ^^^^^^^^^^^^ Association `foo` is defined multiple times. Don't repeat associations. + has_one :blah + end + RUBY + + expect_correction(<<~RUBY) + class Post < ApplicationRecord + has_one :bar + has_one :foo + has_one :blah + end + RUBY + end + + it 'registers an offense with scope block' do expect_offense(<<~RUBY) class Post < ApplicationRecord has_one :foo @@ -72,6 +135,27 @@ class Post < ApplicationRecord describe 'has_and_belongs_to_many' do it 'registers an offense' do + expect_offense(<<~RUBY) + class Post < ApplicationRecord + has_and_belongs_to_many :foos + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Association `foos` is defined multiple times. Don't repeat associations. + has_and_belongs_to_many :bars + has_and_belongs_to_many :foos + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Association `foos` is defined multiple times. Don't repeat associations. + has_and_belongs_to_many :blahs + end + RUBY + + expect_correction(<<~RUBY) + class Post < ApplicationRecord + has_and_belongs_to_many :bars + has_and_belongs_to_many :foos + has_and_belongs_to_many :blahs + end + RUBY + end + + it 'registers an offense with scope block' do expect_offense(<<~RUBY) class Post < ApplicationRecord has_and_belongs_to_many :foos