class RuboCop::Cop::Rails::HasManyOrHasOneDependent

This cop looks for `has_many` or `has_one` associations that don't specify a `:dependent` option.

It doesn't register an offense if `:through` or `dependent: nil` is specified, or if the model is read-only.

@example

# bad
class User < ActiveRecord::Base
  has_many :comments
  has_one :avatar
end

# good
class User < ActiveRecord::Base
  has_many :comments, dependent: :restrict_with_exception
  has_one :avatar, dependent: :destroy
  has_many :articles, dependent: nil
  has_many :patients, through: :appointments
end

class User < ActiveRecord::Base
  has_many :comments
  has_one :avatar

  def readonly?
    true
  end
end

Constants

MSG
RESTRICT_ON_SEND

Public Instance Methods

on_send(node) click to toggle source
# File lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb, line 78
def on_send(node)
  return if active_resource?(node.parent) || readonly_model?(node)
  return if !association_without_options?(node) && valid_options?(association_with_options?(node))
  return if valid_options_in_with_options_block?(node)

  add_offense(node.loc.selector)
end

Private Instance Methods

active_resource?(node) click to toggle source
# File lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb, line 129
def active_resource?(node)
  return false if node.nil?

  active_resource_class?(node)
end
contain_valid_options_in_with_options_block?(node) click to toggle source
# File lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb, line 102
def contain_valid_options_in_with_options_block?(node)
  if (options = with_options_block(node))
    return true if valid_options?(options)

    return false unless node.parent

    return true if contain_valid_options_in_with_options_block?(
      node.parent.parent
    )
  end

  false
end
readonly_model?(node) click to toggle source
# File lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb, line 88
def readonly_model?(node)
  return false unless (parent = node.parent)

  parent.each_descendant(:def).any? { |def_node| readonly?(def_node) }
end
valid_options?(options) click to toggle source
# File lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb, line 116
def valid_options?(options)
  return false if options.nil?

  options = options.first.children.first.pairs if options.first.kwsplat_type?

  return true unless options
  return true if options.any? do |o|
    dependent_option?(o) || present_option?(o)
  end

  false
end
valid_options_in_with_options_block?(node) click to toggle source
# File lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb, line 94
def valid_options_in_with_options_block?(node)
  return true unless node.parent

  n = node.parent.begin_type? || association_extension_block?(node.parent) ? node.parent.parent : node.parent

  contain_valid_options_in_with_options_block?(n)
end