ENGINEERING&RUN

26.2マイルを走る僕の旅

Railsにおける論理削除

今年はほそぼそとしたエントリーでもちゃんとブログを書く。
しっかりとした内容は学習記事にまとめていく。

Railsで論理削除をしたい

destroyメソッド物理的にレコードを削除してしまうと、後で復元ができなくなってしまうなどの弊害がある。
レコードに「削除しました」という情報を持たせ、論理的に削除するのが一般的。

※それでもSIer時代、大手生保システムでは物理削除をしており障害発生時の復元が面倒だったなどがあった。
物理的に削除しないとレコードが増えすぎててしまう、退会後の顧客情報を持ちたくないなどのときは物理削除をすることもある。 scaffold時のdestroyメソッドは物理削除をするので、論理削除に変えてみる。

  def destroy
    @hoge.destroy #物理削除
    respond_to do |format|
      format.html { redirect_to conversations_url, notice: 'Conversation was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

まずdeleteフラグをカラム追加しmigrateする。
:hoge, :deleted_flg, :boolean, null: false, default: false

そしてcontrollerを論理削除に変える。

  def destroy
    @hoge.deleted_flg = true #削除フラグを立て論理削除
    @hoge.save
    respond_to do |format|
      format.html { redirect_to conversations_url, notice: 'Conversation was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

削除されていないレコードかどうか、スコープを定義しておくと便利。
scope :active, where(deleted_flg: false)
アクティブなレコードを取り出すときはこう。
@hoges = Hoge.active

ちなみにparanoiaやkakurenboといったgemも出ているので使うのも手。

rubysherpas/paranoia · GitHub
alfa-jpn/kakurenbo · GitHub

ちなみに今回はフラグを持たせたが、deleted_atのような日付形式にし、Time.nowの値などを設定しておくとより便利。
いつ削除したのかログを見なくてもわかるし、障害発生時に「この日に誤って削除されたレコードを復元したい」のようなことも便利。

こんな形で初歩的な内容でも毎日書いていきたい。