2014-09-30 89 views
4

在Laravel中指定存在驗證規則時是否有引用另一個字段的方法?我想能夠說輸入a必須存在於表a中,輸入b必須存在於表b中,並且表b中列x的值必須等於輸入a。Laravel驗證:與附加列條件存在 - 自定義驗證規則

最好的例子來說明:

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_id存在於teams表(id字段)和game_id列(在teams表)必須等於game_id輸入的值。
  • 如上所述,對於team2_id

所以,如果在我的形式,我進入1game_id,我希望能夠確保兩者team1_idteam2_id球隊表中的記錄具有價值1game_id

我希望這是有道理的。

感謝

+0

我一直在使用這種格式,因爲5.3,它爲我工作。我很確定它是有效的,儘管我沒有在他們的文檔中看到它。 $ this-> mymodel-> create_rules ['company_id'] ='required | exists:companies,id,type_id,'。 $ ID; 這意味着company_id必須存在於其自己的表中,並且type_id字段必須是$ id的值。 – 2017-07-11 13:27:27

回答

6

你想要一個custom validation rule,我會爲此創建一個單獨的類。但爲了簡便起見這裏是相當多的使用內聯封相同:

// 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' 
); 
+0

這似乎工作得很好,謝謝。我將不得不閱讀自定義驗證規則。應該在哪裏放置自定義驗證類?歡呼聲 – Jonathon 2014-09-30 14:22:27

+0

你可能有一些結構(或應該有)爲你的自定義代碼,所以把它放在那裏。在Laravel 5中,您將創建一個新的服務提供商,但這是不同的故事。 – 2014-09-30 14:24:55

1

當你的規則是,你需要在運行驗證之前做出一些改變他們模型屬性。

你可以改變你的規則:

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

編輯

當然,如果你沒有$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

編輯:據說,這不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'       
]; 

第一arguement中存在的方法是表,第二個是我使用了「MC」字段自定義列名。我通過使用'use'關鍵字檢查第二列,然後在where子句中使用該字段。

這非常方便,因爲現在我不再需要自定義驗證規則。

+2

這不適用於Laravel 5.5 – 2017-11-04 23:53:03

+0

@AaronHill,您是如何在laravel v5.5中做的? – LINKeRxUA 2018-01-09 13:33:29

1

試試這個它的事業,對我來說

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