Class: RuboCop::Cop::Rails::FindByOrAssignmentMemoization

Inherits:
Base
  • Object
show all
Extended by:
AutoCorrector
Defined in:
lib/rubocop/cop/rails/find_by_or_assignment_memoization.rb

Overview

Avoid memoizing ‘find_by` results with `||=`.

It is common to see code that attempts to memoize ‘find_by` result by `||=`, but `find_by` may return `nil`, in which case it is not memoized as intended.

Examples:

# bad
def current_user
  @current_user ||= User.find_by(id: session[:user_id])
end

# good
def current_user
  if instance_variable_defined?(:@current_user)
    @current_user
  else
    @current_user = User.find_by(id: session[:user_id])
  end
end

Constant Summary collapse

MSG =
'Avoid memoizing `find_by` results with `||=`.'
RESTRICT_ON_SEND =
%i[find_by].freeze

Instance Method Summary collapse

Instance Method Details

#on_send(node) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/rubocop/cop/rails/find_by_or_assignment_memoization.rb', line 43

def on_send(node)
  assignment_node = node.parent
  find_by_or_assignment_memoization(assignment_node) do |varible_name, find_by|
    next if assignment_node.each_ancestor(:if).any?

    add_offense(assignment_node) do |corrector|
      corrector.replace(
        assignment_node,
        <<~RUBY.rstrip
          if instance_variable_defined?(:#{varible_name})
            #{varible_name}
          else
            #{varible_name} = #{find_by.source}
          end
        RUBY
      )
    end
  end
end