class RuboCop::Cop::Rails::ActiveRecordOverride

Checks for overriding built-in Active Record methods instead of using callbacks.

@example

# bad
class Book < ApplicationRecord
  def save
    self.title = title.upcase!
    super
  end
end

# good
class Book < ApplicationRecord
  before_save :upcase_title

  def upcase_title
    self.title = title.upcase!
  end
end

Constants

ACTIVE_RECORD_CLASSES
BAD_METHODS
MSG

Public Instance Methods

on_def(node) click to toggle source
# File lib/rubocop/cop/rails/active_record_override.rb, line 35
def on_def(node)
  return unless BAD_METHODS.include?(node.method_name)

  parent_class_name = find_parent_class_name(node)
  return unless active_model?(parent_class_name)

  return unless node.descendants.any?(&:zsuper_type?)

  add_offense(node, message: message(node.method_name))
end

Private Instance Methods

active_model?(parent_class_name) click to toggle source
# File lib/rubocop/cop/rails/active_record_override.rb, line 48
def active_model?(parent_class_name)
  ACTIVE_RECORD_CLASSES.include?(parent_class_name)
end
callback_names(method_name) click to toggle source
# File lib/rubocop/cop/rails/active_record_override.rb, line 52
def callback_names(method_name)
  names = %w[before_ around_ after_].map do |prefix|
    "`#{prefix}#{method_name}`"
  end

  names[-1] = "or #{names.last}"

  names.join(', ')
end
find_parent_class_name(node) click to toggle source
# File lib/rubocop/cop/rails/active_record_override.rb, line 66
def find_parent_class_name(node)
  return nil unless node

  if node.class_type?
    parent_class_name = node.node_parts[1]

    return nil if parent_class_name.nil?

    return parent_class_name.source
  end

  find_parent_class_name(node.parent)
end
message(method_name) click to toggle source
# File lib/rubocop/cop/rails/active_record_override.rb, line 62
def message(method_name)
  format(MSG, prefer: callback_names(method_name), bad: method_name)
end