README.md
# DestroyedAt #
[![Build Status](https://travis-ci.org/DockYard/ruby-destroyed_at.svg?branch=master)](http://travis-ci.org/dockyard/ruby-destroyed_at)
[![Dependency Status](https://gemnasium.com/dockyard/ruby-destroyed_at.png?travis)](https://gemnasium.com/dockyard/ruby-destroyed_at)
[![Code Climate](https://codeclimate.com/github/dockyard/ruby-destroyed_at/badges/gpa.svg)](https://codeclimate.com/github/dockyard/ruby-destroyed_at)
## Looking for help? ##
If it is a bug [please open an issue on GitHub](https://github.com/dockyard/destroyed_at/issues).
## Installation ##
Add the `destroyed_at` gem to your `Gemfile`
```ruby
gem 'destroyed_at'
```
You can either mixin the modules on a case-by-case basis:
```ruby
class User < ActiveRecord::Base
include DestroyedAt
end
```
or make the changes globally:
```ruby
class ActiveRecord::Base
include DestroyedAt
end
```
**Please note you will need to make a migration**
Each model's table that is expected to have this behavior **must** have
a `destroyed_at` column of type `DateTime`.
It is recommended that you add an index on the model's `destroyed_at` column,
so that your database does not have to do a table scan for every query.
Only Postgres' query indexes will be of any benefit:
```db
CREATE INDEX ON users WHERE destroyed_at IS NULL;
CREATE INDEX ON users WHERE destroyed_at IS NOT NULL;
```
## Usage ##
Allows you to "destroy" an object without deleting the record or
associated records.
### Destroying ###
Overides `#destroy` to set `#destroyed_at` to the current time on an object. The
default scope of the class is then set to return objects that have not
been destroyed (i.e., have `nil` for their destroyed_at value).
`#destroyed?` will be `true` when your model is destroyed; it will be
`false` when your model has been restored.
```ruby
class User < ActiveRecord::Base
include DestroyedAt
end
user = User.create
user.destroy
# => true
user.destroyed_at
# => <DateTime>
```
#### Warning: Dependent relations with destroy ####
Be careful when destroying models that have `dependent:
:destroy`. This will **delete**, not destroy, the associated model if
said model does not `include DestroyedAt`.
### Restoring ####
When you'd like to "restore" a record, call the `#restore` method on
the instance. This will set its `#destroyed_at` value to `nil`, thereby
including it in the default scope of the class again.
To include this functionality on `has_many through` relationships,
be sure to `include DestroyedAt` on the through model, as well as the
parent model.
```ruby
class User < ActiveRecord::Base
include DestroyedAt
end
user = User.create
user.destroy
user.restore
# => true
user.destroyed_at
# => nil
```
### Destroyed Scope ###
When you include the `DestroyedAt` module, it sets a default scope of
`where(destroyed_at: nil)`. It also defines a scope called `.destroyed`
which removes the default scope and finds the records of a relation
`where.not(destroyed_at: nil)`. This is different than calling `unscoped`
on the class/relation. Where unscoped will remove all scoping from a
relation, `.destroyed` only removes the default scope generated by the
`DestroyedAt` module, making it safe to call on relations.
### Callbacks ###
`before_restore`, `after_restore` and `around_restore` callbacks are added to your
model. They work similarly to the `before_destroy`, `after_destroy` and `around_restore`
callbacks.
```ruby
class User < ActiveRecord::Base
before_restore :before_restore_action
after_restore :after_restore_action
around_restore :around_restore_action
private
def before_restore_action
...
end
def after_restore_action
...
end
def around_restore_action
# before around
yield # restoring...
# after around
end
```
### Validations ###
If you are using the `uniqueness` validator you will need to run it as:
```ruby
validates :email, uniqueness: { conditions: -> { where(destroyed_at: nil) } }
```
Rails will by default not include default_scopes when querying for uniqueness. Rather than monkey
patching the validator we believe this is the best solution.
## Authors ##
* [Michael Dupuis](http://twitter.com/michaeldupuisjr)
* [Brian Cardarella](http://twitter.com/bcardarella)
[We are very thankful for the many contributors](https://github.com/dockyard/destroyed_at/graphs/contributors)
## Versioning ##
This gem follows [Semantic Versioning](http://semver.org)
## Want to help? ##
Please do! We are always looking to improve this gem. Please see our
[Contribution Guidelines](https://github.com/dockyard/destroyed_at/blob/master/CONTRIBUTING.md)
on how to properly submit issues and pull requests.
## Legal ##
[DockYard](http://dockyard.com) Inc. © 2014
[@dockyard](http://twitter.com/dockyard)
[Licensed under the MIT license](http://www.opensource.org/licenses/mit-license.php)