class RuboCop::Cop::Rails::ReadWriteAttribute

end
bar || read_attribute(:foo)
def foo
# good
@example
infinite loop:
‘read_attribute` and `write_attribute` must be used to prevent an
When called from within a method with the same name as the attribute,<br><br>self = val
x = self[:attr]
# good
write_attribute(:attr, val)
x = read_attribute(:attr)
# bad
@example
is why rubocop recommends using square brackets.
Explicitly raising an error in this situation is preferable, and that
an `ActiveModel::MissingAttributeError`.
will return nil, but square brackets will raise
initialized by a partial `select`) then `read_attribute`
If an attribute is missing from the instance (for example, when
methods and recommends square brackets instead.
Checks for the use of the `read_attribute` or `write_attribute`

def build_message(node)

def build_message(node)
  if node.single_line?
    single_line_message(node)
  else
    multi_line_message(node)
  end
end

def multi_line_message(node)

def multi_line_message(node)
  if node.method?(:read_attribute)
    format(MSG, prefer: 'self[:attr]')
  else
    format(MSG, prefer: 'self[:attr] = val')
  end
end

def node_replacement(node)

def node_replacement(node)
  case node.method_name
  when :read_attribute
    read_attribute_replacement(node)
  when :write_attribute
    write_attribute_replacement(node)
  end
end

def on_send(node)

def on_send(node)
  return unless read_write_attribute?(node)
  return if within_shadowing_method?(node)
  add_offense(node, message: build_message(node)) do |corrector|
    corrector.replace(node, node_replacement(node))
  end
end

def read_attribute_replacement(node)

def read_attribute_replacement(node)
  "self[#{node.first_argument.source}]"
end

def single_line_message(node)

def single_line_message(node)
  format(MSG, prefer: node_replacement(node))
end

def within_shadowing_method?(node)

def within_shadowing_method?(node)
  first_arg = node.first_argument
  return false unless first_arg.respond_to?(:value)
  enclosing_method = node.each_ancestor(:def).first
  return false unless enclosing_method
  shadowing_method_name = first_arg.value.to_s
  shadowing_method_name << '=' if node.method?(:write_attribute)
  enclosing_method.method?(shadowing_method_name)
end

def write_attribute_replacement(node)

def write_attribute_replacement(node)
  "self[#{node.first_argument.source}] = #{node.last_argument.source}"
end