From 3971a352ecab261c372c6e87989cdc1951385235 Mon Sep 17 00:00:00 2001 From: viralpraxis Date: Mon, 11 Aug 2025 14:56:21 +0400 Subject: [PATCH] Fix `Rails/OrderArguments` cop false positives ref: https://github.com/rubocop/rubocop-rails/pull/1501 ```shell echo 'User.order("1")' | bundle exec rubocop --stdin bug.rb -A --only Rails/OrderArguments Inspecting 1 file F Offenses: bug.rb:1:12: C: [Corrected] Rails/OrderArguments: Prefer :1 instead. (https://rails.rubystyle.guide/#order-arguments) User.order("1") ^^^ bug.rb:1:13: F: Lint/Syntax: invalid symbol (Using Ruby 3.4 parser; configure using TargetRubyVersion parameter, under AllCops) User.order(:1) bug.rb:1:13: F: Lint/Syntax: unexpected integer; expected a ) to close the arguments (Using Ruby 3.4 parser; configure using TargetRubyVersion parameter, under AllCops) User.order(:1) ^ bug.rb:1:14: F: Lint/Syntax: unexpected ')', expecting end-of-input (Using Ruby 3.4 parser; configure using TargetRubyVersion parameter, under AllCops) User.order(:1) ^ 1 file inspected, 4 offenses detected, 1 offense corrected ==================== User.order(:1) ``` The same happens for these cases: ``` order("1 ASC") # => User.order(:1) order("1 DESC") # => User.order(1: :desc) order("id ASC, 2 DESC") # => User.order(:id, 2: :desc) ``` `order("1")` can be autocorrected to `order(1)`, but this can be done separately. --- ...ils_order_arguments_cop_false_positives.md | 1 + lib/rubocop/cop/rails/order_arguments.rb | 5 ++++ .../rubocop/cop/rails/order_arguments_spec.rb | 26 +++++++++++++++++++ 3 files changed, 32 insertions(+) create mode 100644 changelog/fix_rails_order_arguments_cop_false_positives.md diff --git a/changelog/fix_rails_order_arguments_cop_false_positives.md b/changelog/fix_rails_order_arguments_cop_false_positives.md new file mode 100644 index 0000000000..30867e9fc5 --- /dev/null +++ b/changelog/fix_rails_order_arguments_cop_false_positives.md @@ -0,0 +1 @@ +* [#1510](https://github.com/rubocop/rubocop-rails/pull/1510): Fix `Rails/OrderArguments` cop false positives when using column index argument. ([@viralpraxis][]) diff --git a/lib/rubocop/cop/rails/order_arguments.rb b/lib/rubocop/cop/rails/order_arguments.rb index c4e14c0dfc..75f8d0bd50 100644 --- a/lib/rubocop/cop/rails/order_arguments.rb +++ b/lib/rubocop/cop/rails/order_arguments.rb @@ -52,6 +52,7 @@ def replacement(order_expressions) order_arguments.map! { |arg| extract_column_and_direction(arg.strip) } return if order_arguments.any?(&:nil?) + return if order_arguments.any? { |column_name, _| positional_column?(column_name) } convert_to_preferred_arguments(order_arguments).join(', ') end @@ -68,6 +69,10 @@ def convert_to_preferred_arguments(order_expressions) end end + def positional_column?(column_name) + column_name.match?(/\A\d+\z/) + end + def extract_column_and_direction(order_expression) return unless (column, direction = ORDER_EXPRESSION_REGEX.match(order_expression)&.captures) diff --git a/spec/rubocop/cop/rails/order_arguments_spec.rb b/spec/rubocop/cop/rails/order_arguments_spec.rb index 74b451df73..6e9227dc01 100644 --- a/spec/rubocop/cop/rails/order_arguments_spec.rb +++ b/spec/rubocop/cop/rails/order_arguments_spec.rb @@ -128,4 +128,30 @@ User.order('LEFT(first_name, 1)') RUBY end + + context 'with numeric string literal column name' do + it 'does not register an offense for `order` with a string argument' do + expect_no_offenses(<<~RUBY) + User.order('1') + RUBY + end + + it 'does not register an offense for `order` with multiple string arguments' do + expect_no_offenses(<<~RUBY) + User.order('1', 'last_name') + RUBY + end + + it 'does not registers an offense for `order` with a string argument with DESC direction' do + expect_no_offenses(<<~RUBY) + User.order('1 DESC') + RUBY + end + + it 'does not register an offense for `order` with a string argument with ASC order' do + expect_no_offenses(<<~RUBY) + User.order('1 ASC') + RUBY + end + end end