Skip to content

Instantly share code, notes, and snippets.

@spalladino
Created January 31, 2012 14:42
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save spalladino/1710839 to your computer and use it in GitHub Desktop.
Save spalladino/1710839 to your computer and use it in GitHub Desktop.
How to check if object can be destroyed if it has dependent restrict associations
class ActiveRecord::Base
def can_destroy?
self.class.reflect_on_all_associations.all? do |assoc|
assoc.options[:dependent] != :restrict || (assoc.macro == :has_one && self.send(assoc.name).nil?) || (assoc.macro == :has_many && self.send(assoc.name).empty?)
end
end
end
@kuboon
Copy link

kuboon commented Jul 19, 2013

nil? || empty? == blank?

assoc.options[:dependent] != :restrict || self.send(assoc.name).blank?

@barakargaman
Copy link

:restrict is deprecated. use instead:

  def can_destroy?
    self.class.reflect_on_all_associations.all? do |assoc|
      ( ([:restrict_with_error, :restrict_with_exception].exclude? assoc.options[:dependent]) ||
          (assoc.macro == :has_one && self.send(assoc.name).nil?) ||
          (assoc.macro == :has_many && self.send(assoc.name).empty?) )
    end
  end

@pierrea
Copy link

pierrea commented Feb 10, 2014

@barakarg Thanks for your edit! It works well. πŸ‘

@gustaflindqvist
Copy link

@barakarg πŸ‘

@thattimc
Copy link

Still work in rails 4 πŸ‘

@jpvillaseca
Copy link

And in Rails 5 πŸ‘

@PragmaticEd
Copy link

I think this looks a bit cleaner..

class ActiveRecord::Base

  def can_destroy?
    self.class.reflect_on_all_associations.all? do |assoc|
      [
        %w(restrict_with_error restrict_with_exception).exclude?(assoc.options[:dependent].to_s),
        (assoc.macro == :has_one  && self.send(assoc.name).nil?),
        (assoc.macro == :has_many && self.send(assoc.name).empty?)
      ].include?(true)
    end
  end

end

@ramhoj
Copy link

ramhoj commented Mar 2, 2021

And Rails 6 πŸ‘

My prefered nuance:

class ActiveRecord::Base
  def destroyable?
    self.class.reflect_on_all_associations.all? do |assoc|
      [
        %i[restrict_with_error restrict_with_exception].exclude?(assoc.options[:dependent]),
        (assoc.macro == :has_one && send(assoc.name).nil?),
        (assoc.macro == :has_many && send(assoc.name).empty?)
      ].any?
    end
  end
end

@Petercopter
Copy link

Rails 7 πŸŽ‰ πŸ‘

Thanks everyone!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment