Closet
Closet let you bury your records instead of killing(destroy) them.
Data is valuable even those you think worthless. Closet helps you bury/hide your records in the closet, and restore them whenever you want.
Closet only works with ActiveRecord(Mongoid will support in near future) now.
There is one main difference between closet and other similar packages, Closet didn't change default behaviour of ActiveRecord
, instead brings new functionality on ActiveRecord.
Requirements
"activerecord", "~> 4.0"
Installation
Add this line to your application's Gemfile:
gem 'closet'
And then execute:
$ bundle
Or install it yourself as:
$ gem install closet
Usage
Before do anything, Please add buried_at:datetime
into your desired model.
Run:
$ rails g migration AddBuriedAtToUsers buried_at:datetime:index
and now you have following migration
class AddBuriedAtToUserss < ActiveRecord::Migration
def change
add_column :users, :buried_at, :datetime
add_index :users, :buried_at
end
end
repeat above process for every desired model.
And now include Closet
into the model:
class User < ActiveRecord::Base
# define associations ...
has_many :articles, dependent: :destroy # Closet will be automatically included to class of this association
# After define associations
include Closet
# ....
end
Associations
Closet is smart, after including Closet
into your model, closet will include on every association with dependent
option automatically. So there is no need to include Closet
into model's associations with dependent
option.
Closet only works with following associations: has_many
, has_one
, belongs_to
.
It means you must run the migration for every association with dependent
option.
It worth to mention that dependent
option works exactly like ActiveRecord:
has_many dependent: # Acceptable values: [:destroy, :delete_all]
has_one dependent: # Acceptable values: [:destroy, :delete]
belongs_to dependent: # Acceptable values: [:destroy, :delete]
Instance Methods
All of instance methods are using ActiveRecord Transactions.
Calling #bury
method on User
instance will update the buried_at
column:
user.buried? # Always return in boolean
# => false
user.bury # Always return in boolean
# => true
user.buried?
# => true
user.bury( dependent: false ) # Call bury without dependent callbacks
# => true
#bury!
is similar to #bury
method except it raise Exception
on failure.
is_going_to_failure.bury!
# => Exception
Also if your model have an association with dependent
option, #bury
effects on the association too.
user.articles.map do |article|
article.buried?
end
# => [false, false, ... ]
user.bury! # on succeed returns `true`, on failure raise Exception
# => true
user.buried?
# => true
user.articles.map do |article|
article.buried?
end
# => [true, true, ... ]
user.bury!( dependent: false ) # Call `#bury!` without any effect on associations
# => true
#restore
and #restore!
are inverse of #bury
and #bury!
.
Class Methods
All of class methods are using ActiveRecord Transactions.
If you want to bury all of the records in a table:
User.bury_all
#bury_all
have a dependent argument like #bury
method.
#bury_all!
is similar to #bury_all
method except it raise Exception
on failure.
#restore_all
and #restore_all!
are inverse of #bury_all
and #bury_all!
.
Query Methods
If you're looking for buried records:
User.where_buried
If you're looking for normal records:
User.where_not_buried
If you're looking for all records:
User.all
If you're looking for buried/normal/all records on an association:
user.articles.where_buried
user.articles.where_not_buried
user.articles
as you see Closet didn't change activerecord default behaviour.
Validations
Uniqueness
If you want to use uniqueness validation for records where not buried:
validates :property, uniqueness: { conditions: -> { where_not_buried } }
If you want to use uniqueness validation for records where buried:
validates :property, uniqueness: { conditions: -> { where_buried } }
If you want to use the uniqueness for all of the records:
validates :property, uniqueness: true
Callbacks
Closet provides a few callbacks,bury
callback triggered after/around/before a record gets buried, restore
callback triggered after/around/before a record gets restored.
class User < ActiveRecord::Base
# define associations
include Closet
before_bury :do_something
around_bury :do_something
after_bury :do_something
before_restore :do_something
around_restore :do_something
after_restore :do_something
end
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/closet. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
License
The gem is available as open source under the terms of the MIT License.