CakePHP 2.1 — пользовательское правило проверки — проверка уникальной комбинации значений полей

У меня есть пара столбцов (ip, provider_id), для которых я хочу, чтобы комбинации значений всегда были уникальными. Поэтому я пытаюсь создать пользовательскую функцию проверки. Но у меня проблемы с захватом значения вторичного поля. Это мой код до сих пор в модели:

public $validate = array(
   'ip' => array(
      'rule' => array('uniqueClick', 'provider_id'),
      'message' => 'The click is not unique.'
    )
);  

public function uniqueClick ($ip, $field) {

   $count = $this->find('count', array('conditions' => array('ip' => $ip, 'provider_id' => $field)));
   // echo $field;
   return $count == 0;

}

Итак, проблема в том, что когда я проверяю, какое значение загружается в поле $, это просто строка «provider_id». Я надеялся, что он будет содержать значение поля «provider_id». Кто-нибудь знает, как получить это значение (и все другие значения полей вторичной модели, если необходимо) и отправить его в пользовательскую функцию проверки?

Мое чтение в CookBook и люди, которые обсуждали подобные проблемы, казалось, предполагали, что это решение будет работать, но, к сожалению, не для меня.

Заранее спасибо!


person Community    schedule 23.06.2012    source источник


Ответы (4)


Торт определенно ведет себя так, как должен. Второй параметр, который вы передаете в этом массиве правил, предназначен для передачи как статическое значение.

Однако ваш provider_id должен быть доступен в $this->data['MyModel']['provider_id']

Таким образом, вы должны полностью забыть об этом втором параметре и сделать:

public function uniqueClick ($ip) {

   $count = $this->find('count', array(
      'conditions' => array(
          'ip' => $ip, 
          'provider_id' => $this->data[$this->alias]['provider_id'])
   ));
   return $count == 0;

}

Надеюсь, это поможет!

person joshua.paling    schedule 24.06.2012
comment
Большое спасибо! Очень признателен! - person ; 24.06.2012

Чтобы дополнить ответ Джошуа, массив проверки должен быть построен следующим образом:

// Validation rules
public $validate = array(
   'ip' => array(
      'rule' => array('uniqueClick', 'ip'),
      'message' => 'The click is not unique.'
    )
);  
/** 
 * Checks if there are records on the datasource with the same ip and same provider_id
 * 
 */ 
public function uniqueClick ($ip) {
   $count = $this->find('count', array(
      'conditions' => array(
          'ip' => $ip, 
          'provider_id' => $this->data[$this->alias]['provider_id'])
   ));
   return $count == 0;

}
person jpruizs    schedule 12.12.2012

вы также можете использовать мое правило с возможностью работать с таким количеством полей, сколько вам нужно

попробуйте http://www.dereuromark.de/2011/10/07/maximum-power-for-your-validation-rules/ и https://github.com/dereuromark/tools/blob/master/Model/MyModel.php#L930

так что в основном то же самое, что вы пытались:

'ip' => array(
    'validateUnique' => array(
        'rule' => array('validateUnique', array('provider_id')),
        'message' => 'You already have an entry',
    ),
),
person mark    schedule 24.06.2012
comment
Спасибо, а как это работает? Учитывая, что массив ('user_id') передается как статическое значение в соответствии с ответом от joshua.paling, как я могу передать такие поля, как поле user_id, которое у вас есть? Кроме того, я немного не знаком с приведенным выше синтаксисом, зачем вы добавляете строку 'validate' =› array( -line? И этот материал находится между ними: public $validate = array (вот ваш материал ); ? - person ; 24.06.2012
comment
вы можете легко передать идентификатор провайдера в свой массив данных: $this->data['ModelName']['provider_id'] должно содержать значение, и все это работает из коробки. - person mark; 05.07.2012

Вы можете напрямую использовать это решение, не передавая ничего в правилах проверки, кроме пользовательской уникальной функции.

// Validation rules
public $validate = array(
    'ip' => array(
        'rule' => array('uniqueClick'),
       'message' => 'The click is not unique.'
    )
);  
/** 
 * Checks if there are records on the datasource with the same ip and same provider_id
 * 
 */ 
public function uniqueClick ($ip) {
   $count = $this->find('count', array(
      'conditions' => array(
          'ip' => $ip, 
          'provider_id' => $this->data[$this->alias]['provider_id'])
   ));
   return $count == 0;

}

$this->data[$this->alias]['provider_id'] автоматически получает значение provider_id.

person Babish Shrestha    schedule 03.02.2014