class RuboCop::Cop::Rails::ActionControllerFlashBeforeRender
end
end
render :index<br>flash.now = “msg”
def create
class HomeController < ApplicationController
# good
end
end
render :index<br>flash = “msg”
def create
class HomeController < ApplicationController
# bad
@example
Even though it is usually a mistake, it might be used intentionally.
This cop’s autocorrection is unsafe because it replaces ‘flash` by `flash.now`.
@safety
Check guides.rubyonrails.org/action_controller_overview.html#flash-now<br>Using `flash` assignment before `render` in Rails controllers will persist the message for too long.
def find_ancestor(node, type:)
def find_ancestor(node, type:) node.each_ancestor(type).first end
def followed_by_render?(flash_node)
def followed_by_render?(flash_node) flash_assignment_node = find_ancestor(flash_node, type: :send) context = flash_assignment_node if (node = context.each_ancestor(:if, :rescue).first) return false if use_redirect_to?(context) context = node elsif context.right_siblings.empty? return true end context = context.right_siblings context.compact.any? do |render_candidate| render?(render_candidate) end end
def inherit_action_controller_base?(node)
def inherit_action_controller_base?(node) class_node = find_ancestor(node, type: :class) return false unless class_node action_controller?(class_node) end
def instance_method_or_block?(node)
def instance_method_or_block?(node) def_node = find_ancestor(node, type: :def) block_node = find_ancestor(node, type: :block) def_node || block_node end
def on_send(flash_node)
def on_send(flash_node) return unless flash_assignment?(flash_node) return unless followed_by_render?(flash_node) return unless instance_method_or_block?(flash_node) return unless inherit_action_controller_base?(flash_node) add_offense(flash_node) do |corrector| corrector.replace(flash_node, 'flash.now') end end
def use_redirect_to?(context)
def use_redirect_to?(context) context.right_siblings.compact.any? do |sibling| # Unwrap `return redirect_to :index` sibling = sibling.children.first if sibling.return_type? && sibling.children.one? sibling.send_type? && sibling.method?(:redirect_to) end end