class RuboCop::Cop::Rails::Presence

This cop checks code that can be written more easily using `Object#presence` defined by Active Support.

@example

# bad
a.present? ? a : nil

# bad
!a.present? ? nil : a

# bad
a.blank? ? nil : a

# bad
!a.blank? ? a : nil

# good
a.presence

@example

# bad
a.present? ? a : b

# bad
!a.present? ? b : a

# bad
a.blank? ? b : a

# bad
!a.blank? ? a : b

# good
a.presence || b

Constants

MSG

Public Instance Methods

on_if(node) click to toggle source
# File lib/rubocop/cop/rails/presence.rb, line 76
def on_if(node)
  return if ignore_if_node?(node)

  redundant_receiver_and_other(node) do |receiver, other|
    return if ignore_other_node?(other) || receiver.nil?

    register_offense(node, receiver, other)
  end

  redundant_negative_receiver_and_other(node) do |receiver, other|
    return if ignore_other_node?(other) || receiver.nil?

    register_offense(node, receiver, other)
  end
end

Private Instance Methods

build_source_for_or_method(other) click to toggle source
# File lib/rubocop/cop/rails/presence.rb, line 126
def build_source_for_or_method(other)
  if other.parenthesized? || other.method?('[]') || !other.arguments?
    " || #{other.source}"
  else
    method = range_between(
      other.source_range.begin_pos,
      other.first_argument.source_range.begin_pos - 1
    ).source

    arguments = other.arguments.map(&:source).join(', ')

    " || #{method}(#{arguments})"
  end
end
ignore_if_node?(node) click to toggle source
# File lib/rubocop/cop/rails/presence.rb, line 100
def ignore_if_node?(node)
  node.elsif?
end
ignore_other_node?(node) click to toggle source
# File lib/rubocop/cop/rails/presence.rb, line 104
def ignore_other_node?(node)
  node && (node.if_type? || node.rescue_type? || node.while_type?)
end
message(node, receiver, other) click to toggle source
# File lib/rubocop/cop/rails/presence.rb, line 108
def message(node, receiver, other)
  format(MSG,
         prefer: replacement(receiver, other),
         current: node.source)
end
register_offense(node, receiver, other) click to toggle source
# File lib/rubocop/cop/rails/presence.rb, line 94
def register_offense(node, receiver, other)
  add_offense(node, message: message(node, receiver, other)) do |corrector|
    corrector.replace(node.source_range, replacement(receiver, other))
  end
end
replacement(receiver, other) click to toggle source
# File lib/rubocop/cop/rails/presence.rb, line 114
def replacement(receiver, other)
  or_source = if other&.send_type?
                build_source_for_or_method(other)
              elsif other.nil? || other.nil_type?
                ''
              else
                " || #{other.source}"
              end

  "#{receiver.source}.presence" + or_source
end