2

laravelのバリデーターは、追加の列をチェックする必要がある場合など、既存のデータベース・ルールのカスタマイズを行うことができます。 the manualから例:閉鎖でラベリング検証ツールのカスタム存在ルールに結合を追加するにはどうすればよいですか?

use Illuminate\Validation\Rule; 

Validator::make($data, [ 
    'email' => [ 
     'required', 
     Rule::exists('staff')->where(function ($query) { 
      $query->where('account_id', 1); 
     }), 
    ], 
]); 

queryはtypehintedないので、私はこれはオブジェクトの種類は非常に肯定的ではないよされています。私はDatabaseRule自体がwherewherenotなどについていくつかの機能しか持っていないことを見ることができますが、私はミックスに結合を追加しようとしています。

与えられた例では、account_id = 1のスタッフの電子メールが存在する必要がありますが、チーム(すべてのスタッフがチームの一部であり、separteテーブルです)に特定のプロパティが必要です。 team.active = 1
全スタッフ/チームの事は


コースの一例ですので、最後に私は思ったんだけど:は、どのように私はこのルールに参加を追加することができますので、私たちはスタッフのチームが持っていることを確認してください列「アクティブ」は1です。

私の最初の問題は次のようなものです:そのタイプは何ですか$query私はこのようなものは素晴らしいだろうと想像するだろうが、これが有効である疑う理由はありません。

Rule::exists('staff')->where(function ($query) { 
    $query 
     ->join('team', 'team.team_id', '=', 'staff.team_id') 
     ->where('team.active', 1); 
}) 

これは動作するようには思えません。奇妙なことは、エラーが発生することはありません自体に参加するということですが、無視しているように見える:

列が見つかりません:
で1054不明な列「team.active」「where句」
(SQL: staffから骨材としてのカウント(*)を選択する場所email = -thevalue-と(teamactive = 1)私は、この機能が利用可能であることをギャンブルだと私は、これは(小さな変更を動作するように期待しているだろう

)ここで)、存在しない関数を呼び出しているのでエラーが発生します。しかし、私が得るのは、ビルドされているが結合がないクエリです。

コメントから、その機能に$query->toSQL()を追加しました。これはかなり期待される結果を示していますが、それは私が取得していますエラーで計算しない:

select * from `staff` 
inner join `teams` on `teams`.`team_id` = `staff`.`team_id` 
where `teams`.`active` = ? 
+0

ルールクロージャ内からのvarダンプ '$ query-> toSql()'を試してみて、次を参照してください。

かいつまんで、私はちょうどこのような何かを探してpasses機能を備えたカスタム検証ルールを作成しましたあなたが得るもの。 '$ query'は' Illuminate \ Database \ Query \ Builder'のインスタンスなので、参加することに問題はありません。 – TheFallen

+0

カスタム検証ルールはどうですか? [doc here](https://laravel.com/docs/5.5/validation#custom-validation-rules) – Maraboc

+0

@Marabocはい、それはフォールバックですが、これは最も読みやすく/いい方法ですそれ。 – Nanne

答えて

1

DatabaseRuleは、あなたがその閉鎖で提供何といくつかの魔法をしているようです。最終的には、提供されたwhere句だけを見ているようです(Exists::__toString参照)。クロージャ内のエコーとして結合が保存されていますが、存在するルールはその場所のみを表示します。それが不明な列エラーの理由です。

where私は最初にそこにあったが、それはシステムがそれを文字列にするようにしているので、助けにはならない。ジョインをサポートしているようです。

public function passes($attribute, $value) 
{ 
    $count = DB::table('staff') 
     ->join('teams', 'teams.team_id', '=', 'staff.team_id') 
     ->where([ 
      ['teams.active', '=', 1], 
      ['staff.email', '=', $value] 
     ])->count(); 

    return $count > 0; 
} 
関連する問題