多対多のモデルを作成するときに、中間テーブルを作成することがあると思います。
中間テーブル自体の作成は簡単ですし、論理削除はlaravelではとても簡単にできようになっています。
しかし中間テーブル(pivotテーブル)の論理削除は、laravelで用意されているものではできなかったため、紹介します。
AppUserとcouponが多対多で紐づいている
model,controllerそれぞれはAppUser側からみたものです。
coupon側から見たければ逆にしたらOKです
AppUser,Couponの二つを紐づけるapp_user_couponテーブルでは、deleted_atのカラムを作成しておいてください。
ここが、nullでなければ(日時が入っていれば)削除済み
という形になります。
コントローラー
コントローラーは以下のようになります。
論理削除ですので、
app_user_couponテーブルのdeleted_atカラムに現在時刻を入れます。
$app_user = AppUser::find($id);
$result = DB::table('app_user_coupon')
->where('app_user_id', $app_user->id)
->where('coupon_id', $request->coupon_id)
->update(array('deleted_at' => DB::raw('NOW()')));
「論理削除」機能はこれでOKなのですが、例えばAppUserにひもづくcouponを中間テーブルを介して取得したいときなどは、その両者の関係が論理削除であるという前提にたちモデルに条件を実装した上で、取得する必要があります。
モデル
public function coupons()
{
//中間テーブルで論理削除するために、AppUserにひもづくcouponを取得する時は、app_user_couponのdeleted_atがNULLのものを取得する
return $this->belongsToMany('App\Coupon')->whereNull('app_user_coupon.deleted_at')->withPivot('get_at', 'use_at')->withTimestamps();
}
中間テーブルから取得したい値がidと作成、更新日時だけであるならば、これだけでいいですが、
return $this->belongsToMany('App\Coupon')->whereNull('app_user_coupon.deleted_at')->withTimestamps();
もし、中間テーブルのカラムに取得したいものが他にあるならば、以下のように明記する必要があります。
以下は、app_user_couponテーブルにあるget_atとuse_atのカラムを取得する時の例です。
return $this->belongsToMany('App\Coupon')->whereNull('app_user_coupon.deleted_at')->withPivot('get_at', 'use_at')->withTimestamps();