class RuboCop::Cop::Rails::DeprecatedActiveModelErrorsMethods
user.errors.attribute_names.include?(:attr)
# good
user.errors.keys.include?(:attr)
# bad
user.errors.delete(:name)
# good<br><br>user.errors.messages.clear<br>user.errors.clear
# bad
user.errors.add(:name, ‘msg’)
# good<br><br>user.errors.messages << ‘msg’<br>user.errors << ‘msg’
# bad
@example
The cop has no way of knowing whether a variable is an ActiveModel or not.
which is obviously valid.
This cop is unsafe because it can report ‘errors` manipulation on non-ActiveModel,
@safety
These operations are deprecated in Rails 6.1 and will not work in Rails 7.
Checks direct manipulation of ActiveModel#errors as hash.
def autocorrect(corrector, node)
def autocorrect(corrector, node) receiver = node.receiver range = offense_range(node, receiver) replacement = replacement(node, receiver) corrector.replace(range, replacement) end
def model_file?
def model_file? processed_source.file_path.include?('/models/') end
def offense_range(node, receiver)
def offense_range(node, receiver) receiver = receiver.receiver while receiver.send_type? && !receiver.method?(:errors) && receiver.receiver range_between(receiver.source_range.end_pos, node.source_range.end_pos) end
def on_send(node)
def on_send(node) any_manipulation?(node) do next if target_rails_version <= 6.0 && INCOMPATIBLE_METHODS.include?(node.method_name) add_offense(node) do |corrector| next if skip_autocorrect?(node) autocorrect(corrector, node) end end end
def receiver_matcher(node)
def receiver_matcher(node) model_file? ? receiver_matcher_inside_model(node) : receiver_matcher_outside_model(node) end
def replacement(node, receiver)
def replacement(node, receiver) return '.attribute_names' if node.method?(:keys) key = receiver.first_argument.source case node.method_name when :<< value = node.first_argument.source ".add(#{key}, #{value})" when :clear ".delete(#{key})" end end
def skip_autocorrect?(node)
def skip_autocorrect?(node) return true unless AUTOCORRECTABLE_METHODS.include?(node.method_name) return false unless (receiver = node.receiver.receiver) receiver.send_type? && receiver.method?(:details) && node.method?(:<<) end