読者です 読者をやめる 読者になる 読者になる

波打際のブログさん

主に、プログラミング備忘録など。

kakurenbo-putiというrails4.2に対応した論理削除gemの紹介

はじめに

 kakurenboを公開してから1年が経過し、いろいろ思うところがあり acts_as_paranoid の呪縛から脱却した論理削除gemである kakurenbo-puti を公開しました。

経緯についてはこちらをご覧ください。

kakurenbo-puti

 kakurenbo(acts_as_paranoid系のgem)はrailsの削除機能を論理削除に置き換えることを目的に作られたgemですが、kakurenbo-putiはrailsに論理削除機能を追加する目的で作られたgemです。

 置き換えとは異なり、ActiveRecord魔改造するgemではありませんので、ActiveRecordの内部構造に左右されにくく、コードもシンプル(コアファイルは70行程度)になるため、堅牢さや保守性の面でかなり優秀なgemと言えると思います。


alfa-jpn/kakurenbo-puti · GitHub

基本的な使い方

モデルの準備

 論理削除機能を追加したいモデルに論理削除用のカラムを定義し、クラス内で #soft_deletable メソッドを呼び出します。

論理削除用カラムを追加して

$ rails g migration AddSoftDestroyedAtYourMember soft_destroyed_at:datetime:index

モデルのクラス内でsoft-deletableメソッドを呼びます。

class Member < ActiveRecord::Base
  soft_deletable
end

以上で論理削除機能がモデルに追加できます。
もし、論理削除用に使うカラム名を変更したい場合はオプションで変更可能です。

class Member < ActiveRecord::Base
  soft_deletable :column => :delete_at
end

論理削除

 論理削除時には #soft_destroy メソッドを使います。

member.soft_destroy  # 結果を true/false で返します。
member.soft_destroy! # 削除に失敗した場合に例外が出ます。

member.soft_destroyed? # 論理削除済みのレコードか確認ができます。

復元

 論理削除したレコードの復元には #restore メソッドを使います。

member.restore  # 結果を true/false で返します。
member.restore! # 削除に失敗した場合に例外が出ます。

スコープ

 論理削除されたモデルをスコープから外したり、論理削除されたものだけを取得するにはスコープを使います。

Member.without_soft_destroyed.find(1) # ID1番のレコードが論理削除された場合は取得できない。
Member.only_soft_destroyed.find(1)    # ID1番のレコードが論理削除された場合のみ取得できる。

親子関係の定義

 kakurenbo-putiではあらかじめ親子関係を定義しておき、親のレコードが削除された場合に子のレコードを削除されていることにできます。

soft_deletableのオプションで依存関係を定義します。

class Parent < ActiveRecord::Base
  soft_deletable
end

class Child < ActiveRecord::Base
  # parentが依存アソシエーションであることを定義
  soft_deletable dependent_associations: [:parent]
  belongs_to :parent
end

このように親子関係が定義された状態では次のように動作します。

parent = Parent.create!
child = Child.create!(parent: parent)

child.soft_destroyed? # => false

parent.soft_destroy!

child.soft_destroyed? # => true

Child.without_soft_destroyed.count # => 0
Child.only_soft_destroyed.count    # => 1

使い方は以上になります。
これから新規でプロジェクトを立ち上げる際には kakurenbo-puti をおすすめします。