diff --git a/changelog/fix_a_false_positive_for_rails_action_controller_flash_before_render.md b/changelog/fix_a_false_positive_for_rails_action_controller_flash_before_render.md new file mode 100644 index 0000000000..02897e95b2 --- /dev/null +++ b/changelog/fix_a_false_positive_for_rails_action_controller_flash_before_render.md @@ -0,0 +1 @@ +* [#843](https://github.com/rubocop/rubocop-rails/issues/843): Fix a false positive for `Rails/ActionControllerFlashBeforeRender` when using `flash` in multiline `if` branch before `redirect_to`. ([@koic][]) diff --git a/lib/rubocop/cop/rails/action_controller_flash_before_render.rb b/lib/rubocop/cop/rails/action_controller_flash_before_render.rb index e101de4b3d..9d1f1cd56e 100644 --- a/lib/rubocop/cop/rails/action_controller_flash_before_render.rb +++ b/lib/rubocop/cop/rails/action_controller_flash_before_render.rb @@ -69,9 +69,12 @@ def on_send(flash_node) def followed_by_render?(flash_node) flash_assigment_node = find_ancestor(flash_node, type: :send) context = flash_assigment_node - context = context.parent if context.parent.if_type? + if (if_node = context.each_ancestor(:if).first) + context = if_node + elsif context.right_siblings.empty? + return true + end context = context.right_siblings - return true if context.empty? context.compact.any? do |node| render?(node) diff --git a/spec/rubocop/cop/rails/action_controller_flash_before_render_spec.rb b/spec/rubocop/cop/rails/action_controller_flash_before_render_spec.rb index 4772a1a8dd..6cf9dd10e8 100644 --- a/spec/rubocop/cop/rails/action_controller_flash_before_render_spec.rb +++ b/spec/rubocop/cop/rails/action_controller_flash_before_render_spec.rb @@ -152,6 +152,50 @@ def create end RUBY end + + it 'registers an offense when using `flash` in multiline `if` branch before `render_to`' do + expect_offense(<<~RUBY) + class HomeController < #{parent_class} + def create + if condition + do_something + flash[:alert] = "msg" + ^^^^^ Use `flash.now` before `render`. + end + + render :index + end + end + RUBY + + expect_correction(<<~RUBY) + class HomeController < #{parent_class} + def create + if condition + do_something + flash.now[:alert] = "msg" + end + + render :index + end + end + RUBY + end + + it 'does not register an offense when using `flash` in multiline `if` branch before `redirect_to`' do + expect_no_offenses(<<~RUBY) + class HomeController < #{parent_class} + def create + if condition + do_something + flash[:alert] = "msg" + end + + redirect_to :index + end + end + RUBY + end end end