diff --git a/changelog/fix_rails_duplicate_association_to_handle_alias.md b/changelog/fix_rails_duplicate_association_to_handle_alias.md new file mode 100644 index 0000000000..6386d925f5 --- /dev/null +++ b/changelog/fix_rails_duplicate_association_to_handle_alias.md @@ -0,0 +1 @@ +* [#1356](https://github.com/rubocop/rubocop-rails/issues/1356): Enhance `Rails/DuplicateAssociation` to handle alias. ([@ydakuka][]) diff --git a/lib/rubocop/cop/rails/duplicate_association.rb b/lib/rubocop/cop/rails/duplicate_association.rb index 0373fa4530..19b5d567fb 100644 --- a/lib/rubocop/cop/rails/duplicate_association.rb +++ b/lib/rubocop/cop/rails/duplicate_association.rb @@ -63,11 +63,15 @@ def on_class(class_node) private def register_offense(name, nodes, message_template) - nodes.each do |node| - add_offense(node, message: format(message_template, name: name)) do |corrector| - next if same_line?(nodes.last, node) + last_node = nodes.last - corrector.remove(range_by_whole_lines(node.source_range, include_final_newline: true)) + nodes.each_with_index do |node, index| + add_offense(node, message: format(message_template, name: name)) do |corrector| + if index.zero? + corrector.replace(node, last_node.source) + else + corrector.remove(range_by_whole_lines(node.source_range, include_final_newline: true)) + end end end end diff --git a/spec/rubocop/cop/rails/duplicate_association_spec.rb b/spec/rubocop/cop/rails/duplicate_association_spec.rb index 3fbe151ce2..72b6315c89 100644 --- a/spec/rubocop/cop/rails/duplicate_association_spec.rb +++ b/spec/rubocop/cop/rails/duplicate_association_spec.rb @@ -16,8 +16,8 @@ class Post < ApplicationRecord expect_correction(<<~RUBY) class Post < ApplicationRecord - belongs_to :bar belongs_to :foo + belongs_to :bar belongs_to :blah end RUBY @@ -37,8 +37,8 @@ class Post < ApplicationRecord expect_correction(<<~RUBY) class Post < ApplicationRecord - belongs_to :bar belongs_to :foo, -> { active } + belongs_to :bar belongs_to :blah end RUBY @@ -60,8 +60,8 @@ class Post < ApplicationRecord expect_correction(<<~RUBY) class Post < ApplicationRecord - has_many :bars has_many :foos + has_many :bars has_many :blahs end RUBY @@ -81,12 +81,31 @@ class Post < ApplicationRecord expect_correction(<<~RUBY) class Post < ApplicationRecord - has_many :bars has_many 'foos', -> { active } + has_many :bars has_many :blahs end RUBY end + + it 'registers an offense with alias' do + expect_offense(<<~RUBY) + class Post < ApplicationRecord + belongs_to :foos, -> { active } + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Association `foos` is defined multiple times. Don't repeat associations. + alias bars foos + belongs_to :foos + ^^^^^^^^^^^^^^^^ Association `foos` is defined multiple times. Don't repeat associations. + end + RUBY + + expect_correction(<<~RUBY) + class Post < ApplicationRecord + belongs_to :foos + alias bars foos + end + RUBY + end end describe 'has_one' do @@ -104,8 +123,8 @@ class Post < ApplicationRecord expect_correction(<<~RUBY) class Post < ApplicationRecord - has_one :bar has_one :foo + has_one :bar has_one :blah end RUBY @@ -125,8 +144,8 @@ class Post < ApplicationRecord expect_correction(<<~RUBY) class Post < ApplicationRecord - has_one :bar has_one :foo, -> { active } + has_one :bar has_one :blah end RUBY @@ -148,8 +167,8 @@ class Post < ApplicationRecord expect_correction(<<~RUBY) class Post < ApplicationRecord - has_and_belongs_to_many :bars has_and_belongs_to_many :foos + has_and_belongs_to_many :bars has_and_belongs_to_many :blahs end RUBY @@ -169,8 +188,8 @@ class Post < ApplicationRecord expect_correction(<<~RUBY) class Post < ApplicationRecord - has_and_belongs_to_many :bars has_and_belongs_to_many :foos, -> { active } + has_and_belongs_to_many :bars has_and_belongs_to_many :blahs end RUBY @@ -200,12 +219,12 @@ class Post < ApplicationRecord expect_correction(<<~RUBY) class Post < ApplicationRecord - has_and_belongs_to_many :bars has_and_belongs_to_many :foos, -> { active } + has_and_belongs_to_many :bars has_and_belongs_to_many :blahs - has_one :top_comment, -> { order(likes: :desc) }, class_name: 'Comment' belongs_to :author + has_one :top_comment, -> { order(likes: :desc) }, class_name: 'Comment' end RUBY end