LoginSignup
7
2

More than 3 years have passed since last update.

【Rails】論理削除paranoiaでwith_deleted と joins(もしくはincludes) を併せて使いたい

Last updated at Posted at 2020-08-25

結論

  • Userモデル
has_many :event_users, -> { with_deleted }, dependent: :destroy
  • 実装したいコントローラー
User.joins(:event_users).where(event_users: { event_id: @event.id })

[#<User id: 1, email: "test1@test.co.jp", name: "ユーザー1", nomi_joy_id: "nomijoy1", created_at: "2020-08-24 08:39:25", updated_at: "2020-08-24 08:39:25", belongs: "オーシャンティック航空(株) 東自損3課", position: "副主任", image_id: "c50f454fa1b3c9e86e3033455f6fe88b5620bfd41a9cb92677...">,
 #<User id: 2, email: "test2@test.co.jp", name: "ユーザー2", nomi_joy_id: "nomijoy2", created_at: "2020-08-24 08:39:26", updated_at: "2020-08-24 08:39:26", belongs: "オーシャンティック航空(株) 東自損3課", position: "", image_id: "fdf0cc7df1524ced9088ebbdf2012fba4fd35ed9455bf2987b..."]

詳しく

前提

  • 今回このような多対多のテーブルがあったとする スクリーンショット 2020-08-25 23.01.32.png
  • 今回の場合、論理削除対象のテーブルは飲み会ユーザー(event_user)で、飲み会1に対し飲み会ユーザー1は出席、飲み会ユーザー2は欠席(論理削除)とする。

  • 当然だが、論理削除のgem paranoiaでは何もしないデフォルトの状態では、論理削除されデータは取得されない

EventUser.where(event_id: @event.id)
[#<EventUser:0x00007fa7bd62b7d8
  id: 1,
  user_id: 1,
  event_id: 1,
  fee: 4000,
  fee_status: false,
  deleted_at: nil,
  created_at: Mon, 24 Aug 2020 17:39:40 JST +09:00,
  updated_at: Mon, 24 Aug 2020 17:39:40 JST +09:00>]
  • with_deletedを使うと、論理削除されたデータも拾うことができる
EventUser.with_deleted.where(event_id: @event.id)
[#<EventUser:0x00007fa7bd62b7d8
  id: 1,
  user_id: 1,
  event_id: 1,
  fee: 4000,
  fee_status: false,
  deleted_at: nil,
  created_at: Mon, 24 Aug 2020 17:39:40 JST +09:00,
  updated_at: Mon, 24 Aug 2020 17:39:40 JST +09:00>,
 #<EventUser:0x00007fa7bd62b698
  id: 2,
  user_id: 2,
  event_id: 1,
  fee: 3500,
  fee_status: false,
  deleted_at: nil,
  created_at: Mon, 24 Aug 2020 17:39:40 JST +09:00,
  updated_at: Mon, 24 Aug 2020 17:39:40 JST +09:00>]

やりたいこと

今回は、「ユーザーモデルを起点として飲み会1紐づく飲み会ユーザーを欠席者も含め取得したい」。

  • joins(もしくはincludes)とwherewith_deletedを組み合わせるイメージだがどのように書くんだろう

とりあえず思いつくのをやってみるがエラー

User.joins(:event_users).with_deleted.where(event_users: { event_id: @event.id })

スクリーンショット 2020-08-25 23.23.27.png

いろいろ調べてこれでできた

  • Userモデル
has_many :event_users, -> { with_deleted }, dependent: :destroy
  • 実装したいコントローラー
User.joins(:event_users).where(event_users: { event_id: @event.id })

[#<User id: 1, email: "test1@test.co.jp", name: "ユーザー1", nomi_joy_id: "nomijoy1", created_at: "2020-08-24 08:39:25", updated_at: "2020-08-24 08:39:25", belongs: "オーシャンティック航空(株) 東自損3課", position: "副主任", image_id: "c50f454fa1b3c9e86e3033455f6fe88b5620bfd41a9cb92677...">,
 #<User id: 2, email: "test2@test.co.jp", name: "ユーザー2", nomi_joy_id: "nomijoy2", created_at: "2020-08-24 08:39:26", updated_at: "2020-08-24 08:39:26", belongs: "オーシャンティック航空(株) 東自損3課", position: "", image_id: "fdf0cc7df1524ced9088ebbdf2012fba4fd35ed9455bf2987b..."]

ちなみに

今回とは逆(?)の「多の方が論理削除の対象である時」は下記のようにできる

  • モデル
class Person < ActiveRecord::Base
  belongs_to :group, -> { with_deleted }
end
  • コントローラー
Person.includes(:group).all

(そもそもGitHubで上記を見つけて今回のやり方に気づいた!)

参照

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2