Laravelでは多くのバリデーションが提供されていますが、論理削除を使用している場合はそのままでは使えないものが複数あります。
今回は紐付けをする際に存在チェックで使用するexistsのソフトデリート対応のバリデーションを実装する方法をご紹介します。
カスタムバリデーションの追加
存在チェックをするためのexistsは論理削除に対応されていないため、導入されているテーブルを使用する際には使えません。比較的使用頻度が高いため、今回は他のバリデーション同様にパイプで登録できるようにプロバイダーへ登録します。
exists_soft_delete
まずはプロバイダーファイルを作成するために以下のコマンドをLaravel直下で実行しましょう。
php artisan make:provider ExistsSoftDeleteProvider
以下のディレクトリにファイルが作成されます
app/Providers/ExistsSoftDeleteProvider.php
ファイルの中身を以下のように書き換えます。
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Validator;
class ExistsSoftDeleteProvider extends ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register()
{
//
}
/**
* 論理削除の条件下で存在チェック
*
* @return void
*/
public function boot()
{
Validator::extend('exists_soft_delete', function ($attribute, $value, $parameters, $validator) {
return \DB::table($parameters[0])->where($parameters[1] ?? 'id', $value)
->whereNull('deleted_at')
->exists();
});
}
}
簡単に解説です。
まず、バリデーションを登録するためにValidatorを宣言します。
use Illuminate\Support\Facades\Validator;
boot内の処理についてです。
Validator::extend('exists_soft_delete', function ($attribute, $value, $parameters, $validator) {
return \DB::table($parameters[0])->where($parameters[1] ?? 'id', $value)
->whereNull('deleted_at')
->exists();
});
バリデーション名はextendの第一パラメーターで指定します。今回はexists_soft_deleteとしていますが、もし別称が良ければ覚えやすいものを使ってください。
次にコールバック関数の中身ですが、バリデーションのパラメーターで存在チェック用のテーブルを指定するためDBを使用します。
existsと同様に、第一パラメーターににテーブル名、第二パラメーターにカラム名(省略可)を指定できるようにするため、tableには$parameters[0]、where句を$parameters[1]として 飛んできた値の$valueをチェックにかけます。
カラム名に関しては、省略すれば自動でidをチェックしてもらうよう$parameters[1] ?? ‘id’というようにNull合体演算子を使用します。
このままだと通常のexistsと同じになるため、論理削除に対応させるためwhereNull(‘deleted_at’)を繋げてからexists()で判定チェックをします。
プロバイダー登録
バリデーターを作成したらプロバイダー登録をします。以下のコンフィグファイルに記述を追加します。
config/app.php
130行付近にprovidersの配列が用意されているので、最終行に以下の記述を追加しましょう。
App\Providers\ExistsSoftDeleteProvider::class,
追加したら以下のコマンドを実行します。
php artisan config:cache
最後にエラーメッセージを追加します。以下のファイルにexists_soft_deleteを追加しましょう。
resources/lang/ja/validation.php
※jaファイルを作成していない場合はenに登録してください
配列内のexistsの下に以下の記述を追加します。
'exists_soft_delete' => '選択された:attributeは、有効ではありません。',
これでバリデーションが利用できるようになりました。リクエストファイルのrulesにexistsと同じ要領で記述して使用しましょう。
'user_id' => 'required|exists_soft_delete:users',
これでメッセージが正常に表示されたら完了です。
まとめ
いかがだったでしょうか。
Laravelはカスタム機能が豊富なので、使用頻度の高いバリデーションを実装したい場合は早めにプロバイダー登録をして開発をスムーズに進めましょう。
論理削除を導入している人は、ぜひ参考にしてくださいね。