2012-06-27 131 views
1

什麼是我想要做之間的驗證?
我有三個字段(1隱藏,一個id),並且用戶必須以通過驗證完成其他兩個中的一個。
因此,用戶應該驗證失敗如果這兩個字段爲空,但如果一個人完成傳遞。選擇字段


一個0 B真
A B 0真
A 0 0假

我使用CakePHP V2.1.3所以有機會獲得新的驗證規則增強。

問題
我似乎無法找到一個可靠的方式在同一時間檢查這兩個字段。我迄今從model試圖尋找$this->data和發現,確認只有在通過數據的單個實例在同一時間。所以似乎沒有辦法比較這些字段。

我有什麼到目前爲止

/** 
* Custom validation to see if either of the two fields are set, if neither are, then we fail, if at least one is, we pass 
* @param array $check 
* @return boolean 
*/ 
public function checkAttributes($check){ 
    var_dump($check); 
    var_dump($this->data); 
    echo "<hr>"; 

    // Check for an id value picked from a list 
    if(@is_numeric($check['attribute_value_id']) && isset($this->data['AdvertAttributeValue']['attribute_value_id'])){ 
     return true; 
    } 

    // Check for a date value selected 
    if(@is_array($check['attribute_value_text']) && isset($this->data['AdvertAttributeValue']['attribute_value_text'])){ 
     return true; 
    } 

    // Check for a text value 
    if(@is_string($check['attribute_value_text']) && isset($this->data['AdvertAttributeValue']['attribute_value_text'])){ 
     return true; 
    } 

    return false; 
} 

這似乎並沒有這樣的伎倆,因爲我覺得它不能檢查$this->data因爲它的實例不包含所有相關領域。

數據
我還要提到的是,我傳遞一個大的數字陣列。因此,這些領域多次出現在頁面上,目前12米的尺寸。所以訪問它們直接通過$this->data會很難,因爲他們沒有被命名的尺寸,但$this->data['Model'][<num>]['field'] = value


驗證

public $validate = array(
    'attribute_value_id'=>array(
     'notempty'=>array(
      'rule'=>'checkAttributes', 
      'message'=>'Please select a value for your attribute', 
      'required'=>true, 
     ), 
    ), 
    'attribute_value_text'=>array(
     'notempty'=>array(
      'rule'=>'checkAttributes', 
      'message'=>'You must enter text for this attribute', 
      'required'=>true, 
     ), 
    ) 
); 

數據轉儲
在這裏,我會顯示上面的var_dump()的輸出。我在我的模型兩個驗證規則,一個用於attribute_value_id也是一個attribute_value_text

// An id field selected from a list 
array // $check 
    'attribute_value_id' => string '1' (length=1) 
array // $this->data 
    'AdvertAttributeValue' => 
    array 
     'attribute_value_id' => string '1' (length=1) 
     'id' => string '' (length=0) 

// A text field 
// Validating first time around on the id field 
array // $check 
    'attribute_value_id' => string '' (length=0) 
array // $this->data 
    'AdvertAttributeValue' => 
    array 
     'attribute_value_id' => string '' (length=0) 
     'id' => string '' (length=0) 
     'attribute_value_text' => string '50' (length=2) 
// Validating second time around on the text field 
array // $check 
    'attribute_value_text' => string '50' (length=2) 
array // $this->data 
    'AdvertAttributeValue' => 
    array 
     'attribute_value_id' => string '' (length=0) 
     'id' => string '' (length=0) 
     'attribute_value_text' => string '50' (length=2) 
// A date field 
array // $check 
    'attribute_value_id' => string '' (length=0) 
array // $this->data 
    'AdvertAttributeValue' => 
    array 
     'attribute_value_id' => string '' (length=0) 
     'id' => string '' (length=0) 
     'attribute_value_text' => 
     array 
      'month' => string '06' (length=2) 
      'day' => string '28' (length=2) 
      'year' => string '2012' (length=4) 
+1

驗證發生在什麼階段?例如,如果在保存期間,'$ this-> data'應該包含從控制器傳入'Model :: save()'的所有內容。當你說「驗證只傳遞一個數據實例」時,你是什麼意思? – eaj

+0

@eaj這是保存期間。通過傳遞一個實例,我的意思是一個單一的數組維度。所以在我的數組中,只有一個維度被傳遞給自定義驗證函數。所以如果你有5個字段,你一次只能得到一個。我會添加一個轉儲。 –

+0

如果'$ this-> data'沒有包含你需要驗證的所有信息(就像你在你的問題中所說的那樣),那肯定是因爲你沒有把它全部從你的模型傳遞到Model :: save()控制器?據我瞭解,當你調用'save()'的時候,模型的$ this-> data被設置爲你傳入的數據,然後傳遞給'validate()'。 (也許你已經解決了這個問題,因爲已經過了兩週了;我已經離開了。) – eaj

回答

0

saveAll()方法只是調用saveMany()saveAssociated()適當。默認情況下,這些方法會在保存所有數據之前嘗試驗證所有數據(通過致電validateMany())。然而,正如你可以在the source看到,該函數單獨驗證每一個項目,所以校驗碼將不能訪問其他記錄。

據我所知,你需要在多個記錄之間進行交叉驗證,然後再保存它們。雖然我從來沒有這樣做過,但這聽起來像是在控制器中進行驗證的情況。您可以撥打Model::validate()Model::validateAll()以確保記錄的內部一致性。然後你的控制器也可以實現你的交叉記錄驗證所需的任何邏輯。一旦這樣做了,你可以保存與驗證禁止撥打:

$this->myModel->saveAll($this->request->data, array('validate'=>false)); 

注意,你做任何在此之前,你有你的數據集模型:

$this->myModel->set($this->request->data); 

我意識到這會在控制器中放置很多額外的代碼,理想情況下應該放在模型中。我想這可能是通過模型回調之一完成的,但我不知道如何。

+0

這聽起來像是一種合乎邏輯的方法,因爲它可以分解爲組件,插件或行爲。 –

0

你可以利用模型:: $ DATA或型號:: beforeValidate()。

+0

小心地擴大你的答案,使它有幫助嗎? –