Protect a parent record from deletion when it has specified child records
Ruby
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
lib
spec
tasks
.gitignore
MIT-LICENSE
README.md
Rakefile
init.rb
install.rb
uninstall.rb

README.md

protected_parent_of

Stops the deletion of an ActiveRecord object when members of a specified child association exist.

It adds a "removeable?" method to evaluate whether the object may be deleted and the necessary before_destroy callback.

Example Usage

Adding to your models

The model 'has_many :posts'. Do not allow deletion if there are Post records associated with this object:

class Category < ActiveRecord::Base
  protected_parent_of :posts
end

If it 'has_one :attachement', don't allow deletion until the attachment has been removed. Use the singular, just like the 'has_one'

class Category < ActiveRecord::Base
  protected_parent_of :attachment
end

If necessary, allow several child objects to stay deletion. For example, a polymorphic category model may have:

class Category < ActiveRecord::Base
  protected_parent_of :posts, :comments
end

Depending on taste, you can call protected_parent_of multiple times:

class Category < ActiveRecord::Base
  has_many :posts
  has_many :comments
  protected_parent_of :posts, :comments

  has_one :attachment
  protected_parent_of :attachment
end

When you need something more sophisticated, you can target a method or named_scope. This would block deletion of the category if there were any active posts:

class Category < ActiveRecord::Base
  has_many :posts
  protected_parent_of :active_posts

  def active_posts
    posts.active
  end
end

class Post < ActiveRecord::Base
  named_scope :active, :condition => { :active => true }
end

Using the methods

Once applied to a model, protected_parent_of adds several methods to your model. You can now use 'protected?' and 'removable?'

category = Category.new
category.protected?                 # False
category.removable?                 # True

category = Category.new
category.posts << Post.create
category.protected?                 # True
category.removable?                 # False

And most importantly, it will block deletion

category = Category.create
category.posts = Post.create
category.delete                     # False
category.delete!                    # Raises an exception

License

This code is Uncopyrighted. Its author, Tim Harvey, has released all claims on copyright and has put all the content of this code into the public domain.

No permission is needed to copy, distribute, or modify the content of this code repository. Credit is appreciated but not required.