diff --git a/changelog/fix_an_error_for_rails_action_order.md b/changelog/fix_an_error_for_rails_action_order.md new file mode 100644 index 0000000000..f4b8f9cfe7 --- /dev/null +++ b/changelog/fix_an_error_for_rails_action_order.md @@ -0,0 +1 @@ +* [#841](https://github.com/rubocop/rubocop-rails/issues/841): Fix an error for `Rails/ActionOrder` when using unconventional order of multiple actions. ([@koic][]) diff --git a/lib/rubocop/cop/rails/action_order.rb b/lib/rubocop/cop/rails/action_order.rb index 2cb0a64aa4..99fa9071db 100644 --- a/lib/rubocop/cop/rails/action_order.rb +++ b/lib/rubocop/cop/rails/action_order.rb @@ -6,7 +6,8 @@ module Rails # Enforces consistent ordering of the standard Rails RESTful controller actions. # # The cop is configurable and can enforce any ordering of the standard actions. - # All other methods are ignored. + # All other methods are ignored. So, the actions specified in `ExpectedOrder` should be + # defined before actions not specified. # # [source,yaml] # ---- @@ -75,8 +76,7 @@ def register_offense(previous, current) current = correction_target(current) previous = correction_target(previous) - corrector.replace(current, previous.source) - corrector.replace(previous, current.source) + swap_range(corrector, current, previous) end end @@ -106,6 +106,11 @@ def range_with_comments(node) def range_with_comments_and_lines(node) range_by_whole_lines(range_with_comments(node), include_final_newline: true) end + + def swap_range(corrector, range1, range2) + corrector.insert_before(range2, range1.source) + corrector.remove(range1) + end end end end diff --git a/spec/rubocop/cop/rails/action_order_spec.rb b/spec/rubocop/cop/rails/action_order_spec.rb index 6197e32c94..175ff3ec49 100644 --- a/spec/rubocop/cop/rails/action_order_spec.rb +++ b/spec/rubocop/cop/rails/action_order_spec.rb @@ -18,6 +18,26 @@ def show; end RUBY end + it 'detects unconventional order of multiple actions' do + expect_offense(<<~RUBY) + class UserController < ApplicationController + def create; end + def edit; end + ^^^^^^^^^^^^^ Action `edit` should appear before `create`. + def show; end + ^^^^^^^^^^^^^ Action `show` should appear before `edit`. + end + RUBY + + expect_correction(<<~RUBY) + class UserController < ApplicationController + def show; end + def edit; end + def create; end + end + RUBY + end + it 'supports methods with content' do expect_offense(<<~RUBY) class UserController < ApplicationController @@ -33,10 +53,10 @@ def index; end expect_correction(<<~RUBY) class UserController < ApplicationController def index; end - def show @user = User.find(params[:id]) end + end RUBY end @@ -137,11 +157,11 @@ class TestController < BaseController def index end end - unless Rails.env.development? def edit end end + end RUBY end @@ -181,8 +201,8 @@ def show; end expect_correction(<<~RUBY) class UserController < ApplicationController def show; end - def edit; end def index; end + def edit; end end RUBY end @@ -205,9 +225,9 @@ def index; end class UserController < ApplicationController # index def index; end - # show def show; end + end RUBY end