class RuboCop::Cop::Rails::FindByOrAssignmentMemoization

end
@current_user.do_something
end
@current_user = User.find_by(id: session)
else
@current_user
if defined?(@current_user)
def current_user
# good
end
@current_user.do_something
@current_user ||= User.find_by(id: session)
def current_user
# bad - method contains other code
end
@current_user = User.find_by(id: session)
return @current_user if defined?(@current_user)
def current_user
# good
end
@current_user ||= User.find_by(id: session)
def current_user
# bad - exclusively doing memoization
@example
or the code may have a different purpose than memoization.
This cop is unsafe because detected ‘find_by` may not be Active Record’s method,
@safety
for memoization that are initialized at object creation are ignored.
NOTE: Respecting the object shapes introduced in Ruby 3.2, instance variables used
but ‘find_by` may return `nil`, in which case it is not memoized as intended.
It is common to see code that attempts to memoize `find_by` result by `||=`,
Avoid memoizing `find_by` results with `||=`.

def correct_to_regular_method_definition(corrector, node)

def correct_to_regular_method_definition(corrector, node)
  range = node.loc.assignment.join(node.body.source_range.begin)
  corrector.replace(range, "\n")
  corrector.insert_after(node, "\nend")
end

def initialize_methods

def initialize_methods
  @initialize_methods ||= processed_source.ast.each_descendant(:def).select { |node| node.method?(:initialize) }
end

def instance_variable_assigned?(instance_variable_name)

def instance_variable_assigned?(instance_variable_name)
  initialize_methods.any? do |def_node|
    def_node.each_descendant(:ivasgn).any? do |asgn_node|
      asgn_node.name == instance_variable_name
    end
  end
end

def on_def(node)

When a method body contains only memoization, the correction can be more succinct.
def on_def(node)
  find_by_or_assignment_memoization(node.body) do |variable_name, find_by|
    next if instance_variable_assigned?(variable_name)
    add_offense(node.body) do |corrector|
      corrector.replace(
        node.body,
        <<~RUBY.rstrip
          return #{variable_name} if defined?(#{variable_name})
          #{variable_name} = #{find_by.source}
        RUBY
      )
      correct_to_regular_method_definition(corrector, node) if node.endless?
    end
  end
end

def on_send(node)

def on_send(node)
  assignment_node = node.parent
  find_by_or_assignment_memoization(assignment_node) do |variable_name, find_by|
    next if assignment_node.each_ancestor(:if).any? || instance_variable_assigned?(variable_name)
    add_offense(assignment_node) do |corrector|
      corrector.replace(
        assignment_node,
        <<~RUBY.rstrip
          if defined?(#{variable_name})
            #{variable_name}
          else
            #{variable_name} = #{find_by.source}
          end
        RUBY
      )
    end
  end
end