module DependentRestrict::ClassMethods

Constants

VALID_DEPENDENTS

Public Instance Methods

has_and_belongs_to_many(*args, &extension) click to toggle source
Calls superclass method
# File lib/dependent_restrict.rb, line 51
def has_and_belongs_to_many(*args, &extension)
  options = args.extract_options! || {}
  if VALID_DEPENDENTS.include?(options[:dependent].try(:to_sym))
    reflection = if active_record_4?
      association_id, scope = *args
      restrict_create_reflection(:has_and_belongs_to_many, association_id, scope || {}, options, self)
    else
      association_id = args.first
      create_reflection(:has_and_belongs_to_many, association_id, options, self)
    end
    add_dependency_callback!(reflection, options)
    options.delete(:dependent)
  end
  args << options
  super(*args, &extension)
end
has_many(*args, &extension) click to toggle source
Calls superclass method
# File lib/dependent_restrict.rb, line 35
def has_many(*args, &extension)
  options = args.extract_options! || {}
  if VALID_DEPENDENTS.include?(options[:dependent].try(:to_sym))
    reflection = if active_record_4?
      association_id, scope = *args
      restrict_create_reflection(:has_many, association_id, scope || {}, options, self)
    else
      association_id = args.first
      create_reflection(:has_many, association_id, options, self)
    end
    add_dependency_callback!(reflection, options)
  end
  args << options
  super(*args, &extension)
end
has_one(*args, &extension) click to toggle source

We should be aliasing configure_dependency_for_has_many but that method is private so we can't. We alias has_many instead trying to be as fair as we can to the original behaviour.

Calls superclass method
# File lib/dependent_restrict.rb, line 19
def has_one(*args, &extension)
  options = args.extract_options! || {}
  if VALID_DEPENDENTS.include?(options[:dependent].try(:to_sym))
    reflection = if active_record_4?
      association_id, scope = *args
      restrict_create_reflection(:has_one, association_id, scope || {}, options, self)
    else
      association_id = args[0]
      create_reflection(:has_one, association_id, options, self)
    end
    add_dependency_callback!(reflection, options)
  end
  args << options
  super(*args, &extension)
end

Private Instance Methods

active_record_4?() click to toggle source
# File lib/dependent_restrict.rb, line 97
def active_record_4?
  ::ActiveRecord::VERSION::MAJOR >= 4
end
add_dependency_callback!(reflection, options) click to toggle source
# File lib/dependent_restrict.rb, line 70
def add_dependency_callback!(reflection, options)
  dependent_type = active_record_4? ? options[:dependent] : reflection.options[:dependent]
  name = reflection.name
  name = name.first if name.is_a?(Array) # rails 3
  method_name = "dependent_#{dependent_type}_for_#{name}"
  case dependent_type
  when :rollback, :restrict_with_error
    options.delete(:dependent)
    define_method(method_name) do
      method = reflection.collection? ? :empty? : :nil?
      unless send(name).send(method)
        raise ActiveRecord::Rollback
      end
    end
    before_destroy method_name.to_sym
  when :restrict, :restrict_with_exception
    options.delete(:dependent)
    define_method(method_name) do
      method = reflection.collection? ? :empty? : :nil?
      unless send(name).send(method)
        raise ActiveRecord::DetailedDeleteRestrictionError.new(name, self)
      end
    end
    before_destroy method_name.to_sym
  end
end
restrict_create_reflection(*args) click to toggle source
# File lib/dependent_restrict.rb, line 101
def restrict_create_reflection(*args)
  if ActiveRecord::Reflection.respond_to? :create
    if args[0] == :has_and_belongs_to_many
      args[0] = :has_many
      args[3][:through] = [self.table_name, args[1].to_s].sort.join('_')
    end
    ActiveRecord::Reflection.create *args
  else
    create_reflection(*args)
  end
end