storage_unit

Travis Code Climate Coveralls RubyGem

:recycle: Soft deletion for Rails 4.1+, done right.

Goals

  • Standard set of "soft deletion" methods (trash, recover, trashed?)
  • Explicit storage_unit dependencies (automatically trash associated records)
  • Low-overhead (minimize queries)
  • No validations on recover. (If your records became invalid after they were trashed, check for this yourself)
  • Small, readable codebase

Non-goals

  • Targeting anything less than Rails 4.1
  • Reflection on Rails' associations
  • Generally, anything weird or complex happening behind the scenes

Installation

# In your Gemfile:
gem 'storage_unit'

# In a migration:
add_column :posts, :deleted_at, :datetime

Usage

class Post < ActiveRecord::Base
  has_storage_unit
end

post = Post.create
Post.all # => [post]
post.trashed? # => false

post.trash!
post.trashed? # => true
Post.all # => []
Post.with_deleted # => [post]

new_post = Post.create
Post.with_deleted # => [post, new_post]
Post.deleted_only # => [post]

post.recover!
post.trashed? # => false
Post.all # => []

Cascading trashes

class User < ActiveRecord::Base
  has_storage_unit, cascade: [:posts]
  has_many :posts
end

class Post < ActiveRecord::Base
  has_storage_unit
end

user = User.create
post = Post.create

user.trash!
user.trashed? # => true
post.trashed? # => true

user.recover!
user.trashed? # => false
post.trashed? # => false

Callbacks

class Post < ActiveRecord::Base
  has_storage_unit
  after_recover :ensure_record_is_still_valid

  private
  def ensure_record_is_still_valid
    if !valid?
      # i dunno, trash! this post again? delete it entirely? inform the user? shit is hard.
    end
  end
end

Use a different column

class Post < ActiveRecord::Base
  has_storage_unit column: :trashed_at
end

License

MIT.