Validación “edit unique” en CodeIgniter

Extracto

Es cierto, CodeIniger, tiene muy buen sistema de validaciones, aunque le falten algunas tan tontas como un validador de fechas, y uno que antes de realizar un update en la base de datos compruebe que los campos que hemos declarado como claves UNIQUE sigan siéndolo con los nuevos datos que estamos modificando.

@pedroruizhidalg―La situación es la siguiente: tengo una tabla a la que llamo kanban, cuyo campo kanban_name he descrito como único. Así:

class Migration_Install_kanban extends CI_Migration {

        function up()
        {
            $this->db->query('SET foreign_key_checks=0');
        	$this->dbforge->drop_table('kanban',TRUE);

        	$this->dbforge->add_field(array(
        		'id'	=>	array(
        				'type'				=>	'MEDIUMINT',
        				'constraint'		=>	'8',
        				'unsigned'			=>	TRUE,
        				'auto_increment'	=>	TRUE,
        		),
        		'kanban_name'	=> array(
        				'type'				=>	'VARCHAR',
        				'constraint'		=>	'120',
        				'NOT NULL'			=>	TRUE
        			),
        		'kanban_description'	=> array(
        				'type'				=>	'MEDIUMBLOB'
        			),

                'kanban_datestart'   =>  array(
                        'type'              =>  'DATETIME'
                ),

                'kanban_datefinish'   =>  array(
                        'type'              =>  'DATETIME'
                ),

        		'kanban_datecreation'	=>	array(
        				'type'				=>	'DATETIME'
        		),

                'kanban_idcreator'  =>  array(
                        'type'              =>  'MEDIUMINT',
                        'constraint'        =>  '8',
                        'unsigned'          =>  TRUE,
                ),
                
        		'kanban_ipcreation'		=>	array(
        				'type'				=>	'CHAR',
        				'constraint'		=>	'15'
        		),
                'kanban_datemodification'   =>  array(
                        'type'              =>  'DATETIME'
                ),
                'kanban_idmodification'	=>      array(
                                'type'                  =>      'MEDIUMINT',
                                'constraint'            =>      '8',
                                'unsigned'              =>      TRUE,
                ),
                'kanban_deleted'       =>       array(
                                'type'                  =>      'enum',
                                'constraint'            =>      array('y','n'),
                                'DEFAULT'               =>      'n'
                )
        	));

        	$this->dbforge->add_key('id',TRUE);
        	$this->dbforge->create_table('kanban');
        	$this->db->query('ALTER TABLE kanban ADD FOREIGN KEY(kanban_idcreator) REFERENCES users(id) ON UPDATE CASCADE ON DELETE RESTRICT');
        	$this->db->query('ALTER TABLE kanban ADD CONSTRAINT kanban_name UNIQUE (kanban_name)');
            $this->db->query('SET foreign_key_checks=1');
		}

		function out()
		{
			$this->db->query('SET foreign_key_checks=0');
            $this->dbforge->drop_table('kanban', TRUE);
            $this->db->query('SET foreign_key_checks=1');
		}
}

Descripción

Cuando edito un registro de la tabla kanban necesito seguir manteniendo la unicidad (exclusividad) de valor de campo kanban_name. Me explico, como es valor de este campo no se puede repetir, si el usuario introduce un valor ya existente produciría un error la base de datos debido a la restricción de la clave de tipo UNIQUE, como puede verse arriba. CodeIgniter no soluciona de forma nativa esta circunstancia de ninguna manera.

Empecemos.

Ejecución

Creo application/libraries/MY_Form_validation.php con el siguiente código:

<?php

class MY_Form_validation extends CI_Form_validation{

    public function edit_unique($str, $field)
    {
        sscanf($field, '%[^.].%[^.].%[^.]', $table, $field, $id);
        return isset($this->CI->db)
            ? ($this->CI->db->limit(1)->get_where($table, array($field => $str, 'id !=' => $id))->num_rows() === 0)
            : FALSE;
    }

}

En mi controlador coloco el siguiente código:

 

private function validation_rules($id)
    {
        $validation     =    array(
            array(
                'field'     =>    'kanban_activity_name',
                'label'        =>    $this->lang->line('kanban_activity_name'),
                'rules'        =>    "required|trim|max_length[120]|edit_unique[kanban.kanban_name.$id.]",
                'errors'    =>     array(
                    'edit_unique'    =>    lang('kanban_unique_name')
                    )
            ),
            array(
                'field'     =>    'kanban_description',
                'label'        =>    $this->lang->line('kanban_description'),
                'rules'        =>    'required|trim|min_length[5]|max_length[16777215]',
            ),
            array(
                'field'     =>    'kanban_datestart',
                'label'        =>    $this->lang->line('kanban_date_start'),
                'rules'        =>    'required|callback_date_valid',
                'errors'    =>     array(
                        'date_valid'=> sprintf(lang('kanban_date_bad_format'),set_value('kanban_datestart')),
                    )
            ),
            array(
                'field'     =>    'kanban_datefinish',
                'label'        =>    $this->lang->line('kanban_date_end'),
                'rules'        =>    'required|callback_date_valid|callback_date_after',
                'errors'    =>     array(
                        'date_valid'=> sprintf(lang('kanban_date_bad_format'),set_value('kanban_datefinish')),
                        'date_after'=> sprintf(lang('kanban_date_bad_after'),set_value('kanban_datestart'))
                    )
            )
        );
        $this->validation->set_rules($validation);
    }

 

Como puedes ver hay un argumento obligatorio en la función validation_rules, a partir de ahora lo llamo así:

function index($idkanban)
{
    $this->validation_rules($idkanban);
.../...
}

 

Es decir paso como argumento validation_rules el id del registro que estoy modificando. Es todo.

Epílogo

Como podrás observar el elemento rules del array de kanban_activity_name lo paso entre comillas dobles para que pueda interpretar el valor del argumento id dentro de la cadena de reglas.

Espero y deseo que este artículo haya sido de utilidad. Es muy importante para la continuación de trabajos de calidad recibir algún tipo de feedback por parte de los lectores: es decir, responde con comentarios, evalúa la calidad del trabajo con el sistema de estrellas, comparte con tus redes sociales, da me gusta, marca el blog como favorito. Son pequeños gestos que ayudan a mantener el trabajo de creación.

Clave pública @pedroruizhidalg.pub.key

exlibri, sapere aude

exlibri del autor

#aboutpedroruizhidalgo

♻ miotroblogsite ahorra papel
Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: