prevent_destroy_if_any
This plugin adds ActiveRecord models a way to prevent destroy if specified has_many
, has_one
and/or belongs_to
associations are present. This is achieved by adding a before_destroy
callback that aborts the destroy and adds a base error on the instance when detecting associations.
It's inspired from this stackoverflow answer and was created to factorize this solution when you need it for various models in an application.
It has been tested with ActiveRecord 3 and 4, with Ruby 1.9 and 2+.
Installation
Add this line to your application’s Gemfile:
gem 'prevent_destroy_if_any'
Example usage
A Person model for which you want to prevent destroy when it has an associated user, projects or public profile. Destroy will work if it has associated logs.
class Person < ActiveRecord::Base
belongs_to :user
has_many :projects
has_one :public_profile
has_many :logs
prevent_destroy_if_any :user, :projects, :public_profile
end
Then in Rails you can write your PeopleController destroy action like this:
def destroy
person = Person.find params[:id]
if person.destroy
redirect_to people_url, notice: "Person successfully deleted"
else
redirect_to person, alert: person.errors.full_messages.join
end
end
Error message customization
You can change the default base error message by setting the following key in your locale file(s):
en:
prevent_destroy_if_any:
messages:
cannot_delete_parent_object: "Hey!!! You cannot delete %{parent_object} while %{associated_objects} exist"
License
Copyright © 2013 Florent Guilleux, released under the MIT license.