Never Wastes
Never Wastes adds soft delete to ActiveRecord.
It's similar to acts_as_paranoid but simpler.
Bundler
gem 'never_wastes'
Usage
Migrations
First, add deleted column in your models.
class AddDeletedToYourModels < ActiveRecord::Migration
def change
add_column :your_models, :deleted, :boolean, :null => false, :default => false
end
end
Currently the boolean "deleted" column is required.
If you need a timestamp, you can also add deleted_at column.
class AddDeletedToYourModels < ActiveRecord::Migration
def change
add_column :your_models, :deleted, :boolean, :null => false, :default => false
add_column :your_models, :deleted_at, :datetime
end
end
If you need to have unique index for that table, waste_id will help.
class AddDeletedToYourModels < ActiveRecord::Migration
def change
add_column :your_models, :deleted, :boolean, :null => false, :default => false
add_column :your_models, :deleted_at, :datetime
add_column :your_models, :waste_id, :integer, :null => false, :default => 0
end
end
The waste_id supposed to be 0 when it's not deleted. When the record is softly deleted, its primary key is copied to waste_id to be unique in all deleted records. This helps you add unique index for some typical column like 'name' as the following example;
class AddNameIndexToYourModels < ActiveRecord::Migration
def up
add_index :your_models, [:name, :waste_id], :unique => true
end
# down is needed
end
Declaration
Next step is to specify never_wastes in your model which needs soft delete.
class YourModel < ActiveRecord::Base
never_wastes
end
Use APIs
Then you can use destroy for soft delete.
model.destroy
If you want hard delete, use demolish.
model.demolish
Using Rails 4.0 or later, you can use #demolish! instead of #destroy!.
You can get non-deleted models by default.
models = YourModel.all # deleted models are not included
This gem also changes .delete_all to soft deletion. You can use .demolish_all as the original .delete_all.
If you need to get models with deleted ones, you can use with_deleted.
models = YourModel.with_deleted.all
In your destroy callbacks, you can use destroying_softly? to check if you are in soft delete or hard delete.
after_destroy :delete_files
private
def delete_files
return if destroying_softly?
# delete files associated with the model object
end
Use never_wastes? to check if a model supports soft delete or not.
YourModel.never_wastes?