2010-03-17 26 views
7

Tengo un formulario de registro en el que los usuarios pueden completar dos direcciones de correo electrónico (correo electrónico1 & correo electrónico2). El requisito de marketing es que deben ser únicos (únicos como si tuviéramos 10 usuarios, luego habría 10 * 2 = 20 direcciones de correo electrónico únicas).cakephp isUnique para 2 campos?

El sistema ya está basado en cakephp, entonces, ¿qué me gustaría saber es si hay algo similar a la función isUnique (única en un campo) que pueda hacer esto desde el primer momento? ¿O estoy condenado a codificar esto yo mismo? Gracias por adelantado.

EDIT: construida en el ejemplo de Richard, esta trabajado para mí:

function checkUnique($data, $fields) { 
    if (!is_array($fields)) { 
     $fields = array($fields); 
    } 
    foreach($data as $key) { 
     $checks = $key; 
    } 
    if (empty($checks)) { 
     return true; //allow null 
    } 
    foreach($fields as $key) { 
     $tmp[$key] = $checks; 
    } 
    if (isset($this->data[$this->name][$this->primaryKey])) { 
     $tmp[$this->primaryKey] = "<>".$this->data[$this->name][$this->primaryKey]; 
    } 
    return $this->isUnique($tmp); 
} 
+1

Tenga en cuenta que las versiones más recientes de CakePHP2.x admiten una matriz para http://book.cakephp.org/2.0/en/models/data-validation.html#Model::Validation::isUnique para permitir múltiples campos de manera predeterminada ahora. – mark

Respuesta

12

He publicado una solución a esto en el grupo de Google CakePHP:

http://groups.google.com/group/cake-php/browse_frm/thread/b3a1e4ae3eeb6091/e168f54bac27c163?lnk=gst&q=checkUnique#e168f54bac27c163

Añadir lo siguiente a su AppModel:

 /** 
     * checks is the field value is unqiue in the table 
     * note: we are overriding the default cakephp isUnique test as the 
original appears to be broken 
     * 
     * @param string $data Unused ($this->data is used instead) 
     * @param mnixed $fields field name (or array of field names) to 
validate 
     * @return boolean true if combination of fields is unique 
     */ 
     function checkUnique($data, $fields) { 
       if (!is_array($fields)) { 
         $fields = array($fields); 
       } 
       foreach($fields as $key) { 
         $tmp[$key] = $this->data[$this->name][$key]; 
       } 
       if (isset($this->data[$this->name][$this->primaryKey])) { 
         $tmp[$this->primaryKey] = "<>".$this->data[$this->name][$this- 
>primaryKey]; 

       } 
       return $this->isUnique($tmp, false); 
     } 
} 

y se utiliza en su modelo validar:

 var $validate = array( 
       "name"=>array( 
         "unique"=>array( 
           "rule"=>array("checkUnique", array("name", "institution_id")), 
           "message"=>"A contact with that name already exists for that 
institution" 
         ) 
       ) 
     ); 
+0

¡Gracias por el arranque! Sin embargo, tuve que modificarlo un poco para que funcione para mi situación. Editará la pregunta original con el código final. – jodeci

+0

The 'if (isset ($ this-> data [$ this-> name] [$ this-> primaryKey])) { $ tmp [$ this-> primaryKey] =" <> ". $ This-> data [$ this-> name] [$ this- > primaryKey]; 'debe eliminarse, ya que Cake 2.x realiza esta comprobación por sí mismo en el método' isUnique'. Peor aún, hace que el retorno de isUnique sea incorrecto para mí. – OlivierH

-2

Por lo que yo recuerdo, que tienen a este tipo de la aplicación usando el método beforeSave en el modelo. Tenía un requisito de que un objeto tenga al menos uno de los N fk establecidos, y solo podía hacerlo de esta manera.

Editar: intente con this thread para ver si hay algo allí que resuelva su problema.

-1

Sí y no.

Sí, tendrá que codificarlo usted mismo, pero dentro del componente de validación de CakePHP.

El componente de validación tiene un mecanismo para permitir reglas de validación personalizadas. Básicamente, pones un nombre de función dentro de $ validate (como lo harías normalmente). Tienes que definir la función; en este caso, es bastante simple (simplemente haga cumplir su doble requisito de Unique).

http://book.cakephp.org/2.0/en/models/data-validation.html#custom-validation-rules

11

checkUnique podría simplemente escribirse como un contenedor para isUnique.

class AppModel extends Model { 
    public function checkUnique($ignoredData, $fields, $or = true) { 
     return $this->isUnique($fields, $or); 
    } 
} 

y se utiliza en el modelo de validación:

public $validate = array(
    'name' => array(
     'unique' => array(
      'rule' => array('checkUnique', array('name', 'institution_id'), false), 
      'message' => 'A contact with that name already exists for that 
institution' 
     ) 
    ) 
); 
+0

Esta es una respuesta mucho más simple que la originalmente aceptada. –

+1

@KimStacks Esta funcionalidad no estaba disponible en CakePHP cuando escribí mi respuesta original – RichardAtHome

+0

Lo tengo. Gracias por decirme @RichardAtHome –

-1

A riesgo de ser golpeado en la cabeza y los hombros por ofrecer una solución no CakePHP, permítanme presentar lo siguiente.

Cree un índice único en su base de datos sobre cuantas columnas necesite.

sintaxis SQL estándar para esto es:

create unique index {IndexName} on {Table} ({Column}, {Column}, ...) 

Coloque el "$ this-> Modelo-> save()" comando dentro de un bloque "try/catch". En el bloque "catch", prueba la excepción para el código de error. En MySQL, una violación de clave única es el código de error 23000, pero también debe estar preparado para otros posibles errores.

Es rápido y simple y no implica contar paréntesis de matriz.

Debe siempre Coloque el código de acceso a la base de datos dentro de un bloque "try/catch" de todos modos. Parte de su manejo de excepciones debe incluir el registro de cualquier mensaje de error inesperado. No puede esperar que CakePHP haga todo para usted.

+0

Veo que mi respuesta fue rechazada. No importa. Yo sostengo que mi solución es más simple, probablemente más rápida, y ciertamente implica mucho menos codificación que la respuesta "correcta" designada. – UncaAlby

2

From cakePHP 2.0 documentation:

Puede validar que un conjunto de campos son únicos proporcionando múltiples campos y establecer $ o falsa:

public $validate = array(
    'email' => array(
     'rule' => array('isUnique', array('email', 'username'), false), 
     'message' => 'This username & email combination has already been used.' 
    ) 
); 

Asegúrese de incluir el campo original en la lista de campos cuando haciendo una regla única en múltiples campos.

Si un campo listado no está incluido en los datos del modelo, entonces se trata como un valor nulo. Puede considerar marcar los campos enumerados según sea necesario.