2012-06-27 2 views
1

Что я пытаюсь сделать?
У меня есть три поля (1 скрыто, идентификатор), и пользователь должен выполнить один из двух других, чтобы пройти проверку.
Таким образом, пользователь должен пропустить проверку, если оба поля пусты, но передайте, если они завершены.Выбрать валидацию между полями


A 0 B Правда
A B 0 Правда
A 0 0 Ложное

Я использую CakePHP v2.1.3 поэтому имеют доступ к усовершенствованиям правил проверки.

Проблема
Я не могу найти надежный способ проверить оба поля одновременно. Я до сих пор пробовал посмотреть $this->data с model и обнаружил, что валидация передаёт только один экземпляр данных за раз. Таким образом, похоже, нет способа сравнить поля.

То, что я до сих пор

/** 
* 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


Validation

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 this> этой модели 'устанавливаются в данные, которые вы передаете. Это, в свою очередь, передается' 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); 

I поймите, что это добавляет много дополнительного кода в контроллер, который в идеале должен быть в модели. Полагаю, возможно, что это можно сделать с помощью одного из обратных вызовов модели, но я не уверен, как это сделать.

+0

Это звучит как логический подход, поскольку его можно разбить на компонент, плагин или поведение. –

0

Вы можете использовать Model :: $ данных или модели :: beforeValidate().

+0

Помогите расширить свой ответ, чтобы сделать его полезным? –

Смежные вопросы