class RuboCop::Cop::Rails::Presence

a.presence || b
# good
!a.blank? ? a : b
# bad
a.blank? ? b : a
# bad
!a.present? ? b : a
# bad
a.present? ? a : b
# bad
@example
a.presence
# good
!a.blank? ? a : nil
# bad
a.blank? ? nil : a
# bad
!a.present? ? nil : a
# bad
a.present? ? a : nil
# bad
@example
`Object#presence` defined by Active Support.
Checks code that can be written more easily using

def build_source_for_or_method(other)

def build_source_for_or_method(other)
  if other.parenthesized? || other.method?('[]') || other.arithmetic_operation? || !other.arguments?
    " || #{other.source}"
  else
    method = method_range(other).source
    arguments = other.arguments.map(&:source).join(', ')
    " || #{method}(#{arguments})"
  end
end

def current(node)

def current(node)
  if !node.ternary? && node.source.include?("\n")
    "#{node.loc.keyword.with(end_pos: node.condition.loc.selector.end_pos).source} ... end"
  else
    node.source.gsub(/\n\s*/, ' ')
  end
end

def ignore_if_node?(node)

def ignore_if_node?(node)
  node.elsif?
end

def ignore_other_node?(node)

def ignore_other_node?(node)
  node&.type?(:if, :rescue, :while)
end

def message(node, receiver, other)

def message(node, receiver, other)
  prefer = replacement(receiver, other, node.left_sibling).gsub(/^\s*|\n/, '')
  current = current(node).gsub(/^\s*|\n/, '')
  format(MSG, prefer: prefer, current: current)
end

def method_range(node)

def method_range(node)
  range_between(node.source_range.begin_pos, node.first_argument.source_range.begin_pos - 1)
end

def on_if(node)

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

def register_offense(node, receiver, other)

def register_offense(node, receiver, other)
  add_offense(node, message: message(node, receiver, other)) do |corrector|
    corrector.replace(node, replacement(receiver, other, node.left_sibling))
  end
end

def replacement(receiver, other, left_sibling)

def replacement(receiver, other, left_sibling)
  or_source = if other&.send_type?
                build_source_for_or_method(other)
              elsif other.nil? || other.nil_type?
                ''
              else
                " || #{other.source}"
              end
  replaced = "#{receiver.source}.presence#{or_source}"
  left_sibling ? "(#{replaced})" : replaced
end