class RuboCop::Cop::Rails::ReflectionClassName
has_many :accounts, class_name: ‘Account’
# good
has_many :accounts, class_name: Account.name
has_many :accounts, class_name: Account
# bad
@example
constant or method return value specified to ‘class_name` is a string.
This cop is unsafe because it cannot be determined whether
@safety
the definition of a reflection is a string.
Checks if the value of the option `class_name`, in
def autocorrect(corrector, class_config)
def autocorrect(corrector, class_config) class_value = class_config.value replacement = const_or_string(class_value) return unless replacement corrector.replace(class_value, replacement.source.inspect) end
def on_send(node)
def on_send(node) association_with_reflection(node) do |reflection_class_name| return if reflection_class_name.value.send_type? && !reflection_class_name.value.receiver&.const_type? return if reflection_class_name.value.lvar_type? && str_assigned?(reflection_class_name) add_offense(reflection_class_name) do |corrector| autocorrect(corrector, reflection_class_name) end end end
def reflection_class_value?(class_value)
def reflection_class_value?(class_value) if class_value.send_type? !class_value.method?(:to_s) || class_value.receiver&.const_type? else !ALLOWED_REFLECTION_CLASS_TYPES.include?(class_value.type) end end
def str_assigned?(reflection_class_name)
def str_assigned?(reflection_class_name) lvar = reflection_class_name.value.source reflection_class_name.ancestors.each do |nodes| return true if nodes.each_child_node(:lvasgn).detect do |node| lhs, rhs = *node lhs.to_s == lvar && ALLOWED_REFLECTION_CLASS_TYPES.include?(rhs.type) end end false end