web-dev-qa-db-ja.com

Laravel検証:追加の列条件で存在-カスタム検証ルール

Laravelに存在検証ルールを指定するときに別のフィールドを参照する方法はありますか?入力aはテーブルaに存在しなければならず、入力bはテーブルbに存在し、かつテーブルbの列xの値は入力aと等しくなければならない、と言いたいです。

例で説明するのが最適です:

public $rules = array(
    'game_id' => 'required|exists:games,id',
    'team1_id' => 'required|exists:teams,id,game_id,<game_id input value here>',
    'team2_id' => 'required|exists:teams,id,game_id,<game_id input value here>'
);

したがって、検証ルールを使用して、次のことを確認できるようにします。

  • game_idgamesテーブル(idフィールド)内に存在します
  • team1_idteamsテーブル(idフィールド)内に存在し、game_id列(teamsテーブル内)はgame_id入力の値と等しくなければなりません。
  • 上記のteam2_idのように

したがって、フォームで1game_idと入力した場合、team1_idteam2_idの両方のチームテーブル内のレコードの1の値がgame_idになるようにする必要があります。

これが理にかなっていることを願っています。

ありがとう

13
Jonathon

カスタム検証ルール が必要で、このために別のクラスを作成します。ただし、簡潔にするために、インラインクロージャを使用してもほぼ同じです。

// give it meaningful name, I'll go with game_fixture as an example
Validator::extend('game_fixture', function ($attribute, $value, $parameters, $validator) 
{
    if (count($parameters) < 4)
    {
        throw new \InvalidArgumentException("Validation rule game_fixture requires 4 parameters.");
    }

    $input    = $validator->getData();
    $verifier = $validator->getPresenceVerifier();

    $collection = $parameters[0];
    $column     = $parameters[1];
    $extra      = [$parameters[2] => array_get($input, $parameters[3])];

    $count = $verifier->getMultiCount($collection, $column, (array) $value, $extra);

    return $count >= 1;
});

次に、単にこれを使用します:

$rules = array(
    'game_id' => 'required|exists:games,id',

    // last parameter here refers to the 'game_id' value passed to the validator
    'team1_id' => 'required|game_fixture:teams,id,game_id,game_id',
    'team2_id' => 'required|game_fixture:teams,id,game_id,game_id'
);
12
Jarek Tkaczyk

編集:おそらくこれはLaravel 5.5で動作しません。@ user3151197答えはトリックを行う可能性があります。

私はLaravel 5.4を使用しており、既存の一意のルールにカスタム Rule を追加する機能があります。これは5.3で登場したと思います

私のシナリオは次のとおりです。電子メール検証テーブルがあり、渡されたマシンコードとアクティベーションコードが同じ行に存在することを確認したい。

必ずuse Illuminate\Validation\Rule;を含めてください

$activationCode = $request->activation_code;                                   

$rules = [                                                                     
    'mc' => [                                                                  
        'required',                                                            
        Rule::exists('email_verifications', 'machineCode')                     
        ->where(function ($query) use ($activationCode) {                      
            $query->where('activationCode', $activationCode);                  
        }),                                                                    
    ],                                                                         
    'activation_code' => 'required|integer|min:5',                             
    'operating_system' => 'required|alpha_num|max:45'                          
];

Existsメソッドの最初の引数はテーブルで、2番目は「mc」フィールドに使用しているカスタム列名です。 「use」キーワードを使用して確認する2番目の列を渡し、where句でそのフィールドを使用します。

これは、カスタムの検証ルールが不要になったため、非常に便利です。

14
roerjo

ルールはモデルプロパティであるため、バリデーターを実行する前にルールを変更する必要があります。

ルールを次のように変更できます。

public $rules = array(
    'game_id' => 'required|exists:games,id',
    'team1_id' => 'required|exists:teams,id,game_id,{$game_id}',
    'team2_id' => 'required|exists:teams,id,game_id,{$game_id}'
);

次に、{$game_id}文字列の代わりにループを使用して正しい値を挿入する必要があります。

私はルールを編集するために私の場合にどのようにそれをしたかを示すことができます:

public function validate($data, $translation, $editId = null)
{
    $rules = $this->rules;

    $rules = array_intersect_key($rules, $data);

    foreach ($rules as $k => $v) {
        $rules[$k] = str_replace('{,id}',is_null($editId) ? '' : ','.$editId , $v);
    }

    $v = Validator::make($data, $rules, $translation);

    if ($v->fails())
    {
        $this->errors = $v->errors();
        return false;
    }

    return true;
}

{$game_id}$data['game_id']に変更する場合も同じことができます(私の場合は{,id},$editIdに変更しました

[〜#〜] edit [〜#〜]

もちろん、$rulesがプロパティとして設定されていない場合は、次のようにするだけで済みます。

$rules = array(
    'game_id' => 'required|exists:games,id',
    'team1_id' => 'required|exists:teams,id,game_id,'.$data['game_id'],
    'team2_id' => 'required|exists:teams,id,game_id,'.$data['game_id']
);

データセットがある場所。

4

これを試してみてください

'email'=>'required|unique:admintable,Email,'.$adminid.',admin_id',
2
user3151197