⚠ In case you've missed it, we have migrated to our new website, with a brand new forum. For more details about the migration you can read our blog post for website migration. This is an archived forum. ⚠

  •     

profile picture

[SOLVED] Set rules is unique doesn't work



clare
  • profile picture
  • Member

Posted 04 January 2012 - 12:16 PM

Hi,

Is there any way to have different validation rules for insert and update? For example, I want the usernames to be unique, but if i do

$this->grocery_crud->set_rules('username', 'Username','trim|required|xss_clean|is_unique[Users.username]');

it doesn't allow me to update the record because it thinks the username is being duplicated...

Thanks

web-johnny
  • profile picture
  • Administrator
  • 1,166 posts

Posted 05 January 2012 - 23:23 PM

[quote name='clare' timestamp='1325679417' post='220']
Hi,

Is there any way to have different validation rules for insert and update? For example, I want the usernames to be unique, but if i do

$this->grocery_crud->set_rules('username', 'Username','trim|required|xss_clean|is_unique[Users.username]');

it doesn't allow me to update the record because it thinks the username is being duplicated...

Thanks
[/quote]

The only way you can do it now without hacking the core is this:

function your_function($operation = null)
{
....
$this->grocery_crud->....
if( $operation == 'insert_validation' || $operation == 'insert')
{
$this->grocery_crud->set_rules('username', 'Username','trim|required|xss_clean|is_unique[Users.username]');
}
else
{
$this->grocery_crud->set_rules('username', 'Username','trim|required|xss_clean');
}
$this->grocery_crud->....
$output = $this->grocery_crud->render();

....
}


I know this is not the best solution, but it will work for sure .

The best thing for me to do its to use custom callback for the set_rule. You can see more at: http://codeigniter.com/user_guide/libraries/form_validation.html#callbacks

clare
  • profile picture
  • Member

Posted 09 January 2012 - 20:49 PM

Hi thanks for your reply,

Your solution works if the username is only ever changed on insert, but the username can still be changed to another already existing username on update.... is there a way of making the username field un-editable on update?

Thanks

web-johnny
  • profile picture
  • Administrator
  • 1,166 posts

Posted 11 January 2012 - 02:38 AM

This solution works for grocery CRUD version 1.1.8 or later
You can use the callback function, so the solution of your problem is:


function your_function($operation = null)
{
....
$this->grocery_crud->....
$this->grocery_crud->set_rules('username', 'Username','trim|required|xss_clean|callback_username_check');
$this->grocery_crud->....
$output = $this->grocery_crud->render();
....
}
public function username_check($str)
{
$id = $this->uri->segment(4);
if(!empty($id) && is_numeric($id))
{
$username_old = $this->db->where("id",$id)->get('users')->row()->username;
$this->db->where("username !=",$username_old);
}

$num_row = $this->db->where('username',$str)->get('users')->num_rows();
if ($num_row >= 1)
{
$this->form_validation->set_message('username_check', 'The username already exists');
return FALSE;
}
else
{
return TRUE;
}
}


Try it and inform us, just for the other users to know about similar issues.

clare
  • profile picture
  • Member

Posted 11 January 2012 - 13:49 PM

Yep the callback function works well :)

I needed to add more lines into the library, as the version I have doesn't seem to be up-to-date (it was just some extra stuff from the line surrounding the edits in those 2 commits).

I've tried adding a callback function for other fields and it seems to work perfectly :)

Thanks very much!
Clare

arif_avi
  • profile picture
  • Member

Posted 12 January 2012 - 07:04 AM

This will check both before insert and during updates...
@web-johnny Thanks for the last post... i just modified it for my use...


/***** rule + code *****/
$crud->set_rules('batchName','Batch Name','trim|required|xss_clean|callback_checkUniqueBatchName');
function checkUniqueBatchName($str){
//is_unique['.TBL_BATCH.'.batchName]
$id = $this->uri->segment(4);
$old_name = "";
$result = null;

if(!empty($id) && is_numeric($id))
{
$this->db->where("batchId", $id);
$result = $this->db->get(TBL_BATCH);
if($result->num_rows() > 0)
{
foreach($result->result() as $row)
{
$old_name = $row->batchName;
}

$this->db->where("batchName !=", $old_name);
$this->db->where("batchName", $str);
$num_rows = $this->db->get(TBL_BATCH)->num_rows();
if($num_rows > 0)
{
$this->form_validation->set_message("checkUniqueBatchName","The %s already Exist. Please try a different batch name.");
return false;
}
}
}
else
{
$this->db->where("batchName", $str);
$num_rows = $this->db->get(TBL_BATCH)->num_rows();
if($num_rows > 0)
{
$this->form_validation->set_message("checkUniqueBatchName","The %s already Exist. Please try a different batch name.");
return false;
}
}
}

Lucas
  • profile picture
  • Member

Posted 11 March 2012 - 17:07 PM

ok but only update option ?

function proyectos_participantes_consulta() {
$this->load->library('session');
if (!$this->session->userdata('proyecto'))
$this->session->set_userdata('proyecto', $this->input->post('proyecto'));
$this->load->helper(array('form', 'url'));
$this->load->library('form_validation');
$crud = new grocery_CRUD();
$crud = new grocery_CRUD();
$crud->set_table('fs_usuario_proyecto');
$crud->set_theme('flexigrid');
// $crud->set_rules('fs_usuario_id', 'Username', 'callback_username_check');
$crud->where('fs_proyecto_id', $this->session->userdata('proyecto'));
$crud->set_subject('Participantes por Proyecto');
$crud->unset_columns('id', 'usuario_proyecto_nombre_heredado');
$crud->set_relation('fs_proyecto_id', 'fs_proyecto', 'proyecto_nombre');
$crud->set_relation('fs_rol_id', 'fs_rol', 'rol_nombre');
$crud->set_relation('fs_usuario_id', 'fs_usuario', '{usuario_nombre} {usuario_apellido} ');
$crud->display_as('fs_proyecto_id', 'Proyecto');
$crud->display_as('fs_rol_id', 'Rol en el Proyecto');
$crud->display_as('fs_usuario_id', 'Usuario');
$crud->callback_after_insert(array($this, 'nombre_participantes'));
$crud->callback_after_update(array($this, 'nombre_participantes'));
$crud->callback_after_update(array($this, 'username_check'));
$this->grocery_crud->callback_before_insert(array($this, 'autoProyecto'));
$crud->change_field_type('fs_proyecto_id', 'hidden', $this->session->userdata('proyecto'));
$crud->fields('fs_proyecto_id', 'fs_rol_id', 'fs_usuario_id');
$crud->edit_fields('fs_rol_id');
$output = $crud->render();
$this->_example_output($output);
}
// Verifica que el usuario no se encuentre ya registrado en el proyecto
function username_check($str,$hey=null) {
if ($this->proyecto_model->usuarioProyecto($str['fs_usuario_id'], $this->session->userdata('proyecto')) == true) {
$this->form_validation->set_message('Usuario', 'El Usuario ya se encuentra registrado en el Proyecto"');
return FALSE;
} else {
return TRUE;
}
}

rikoy
  • profile picture
  • Member

Posted 29 June 2012 - 02:56 AM

thanks jhonny, can do use one function to handle this many same process?

web-johnny
  • profile picture
  • Administrator
  • 1,166 posts

Posted 01 July 2012 - 01:09 AM

Well I want for the future to add something to this:


$crud->unique_fields('field1','field2','field3',...);

Update: Guys whoever is intrested to find an external library for the functionality $crud->unique_fields you can check my answer at stackoverflow at: http://stackoverflow.com/questions/13537503/custom-is-unique-logical-key-validation-or-callback


rteranm
  • profile picture
  • Member

Posted 18 July 2012 - 22:37 PM

[quote name='web-johnny' timestamp='1326249510' post='262']
This solution works for grocery CRUD version 1.1.8 or later
You can use the callback function, so the solution of your problem is:


function your_function($operation = null)
{
....
$this->grocery_crud->....
$this->grocery_crud->set_rules('username', 'Username','trim|required|xss_clean|callback_username_check');
$this->grocery_crud->....
$output = $this->grocery_crud->render();
....
}
public function username_check($str)
{
$id = $this->uri->segment(4);
if(!empty($id) && is_numeric($id))
{
$username_old = $this->db->where("id",$id)->get('users')->row()->username;
$this->db->where("username !=",$username_old);
}

$num_row = $this->db->where('username',$str)->get('users')->num_rows();
if ($num_row >= 1)
{
$this->form_validation->set_message('username_check', 'The username already exists');
return FALSE;
}
else
{
return TRUE;
}
}


Try it and inform us, just for the other users to know about similar issues.
[/quote]


[b]great code, but when you want upgrade "The username already exists"[/b]

regards

Nico
  • profile picture
  • Member

Posted 03 August 2012 - 03:11 AM

But there has to be a way to get the primary key on edition for the rule(which you don't have on addition...so, it would help to know what is the current operation) which could help to find, if the username is not unique, if at least it is the user's one. if so, the update runs, else, an error appears.


It could prevent to have to disable the username field during edition...

((I have that issue and instead of starting another thread, I use the one that has an issue slightly different than me...I don't know if it's a problem...))

I need to have access to the username but keep the rule that verify if it is unique even if i have to make a callback...



[UPDATE] Oops...i didn't see the SOLVED...sorry, should I start a new thread then????

casachit
  • profile picture
  • Member

Posted 09 August 2012 - 10:14 AM

[quote name='web-johnny' timestamp='1326249510' post='262']
This solution works for grocery CRUD version 1.1.8 or later
You can use the callback function, so the solution of your problem is:


function your_function($operation = null)
{
....
$this->grocery_crud->....
$this->grocery_crud->set_rules('username', 'Username','trim|required|xss_clean|callback_username_check');
$this->grocery_crud->....
$output = $this->grocery_crud->render();
....
}
public function username_check($str)
{
$id = $this->uri->segment(4);
if(!empty($id) && is_numeric($id))
{
$username_old = $this->db->where("id",$id)->get('users')->row()->username;
$this->db->where("username !=",$username_old);
}

$num_row = $this->db->where('username',$str)->get('users')->num_rows();
if ($num_row >= 1)
{
$this->form_validation->set_message('username_check', 'The username already exists');
return FALSE;
}
else
{
return TRUE;
}
}


Try it and inform us, just for the other users to know about similar issues.
[/quote]

I dunno why this code is not working for me... It keeps throwing error when updating similar to is_unique error...

arif rh
  • profile picture
  • Member

Posted 12 September 2012 - 09:33 AM

I have read how to make the same rule for is_unique when editing and adding entries, but it doesn't work when in grocery CRUD, just work when adding data, but when update data it always says that "The %s field must contain a unique value.".

Here's the code, how can I modify it to make it work with grocery CRUD? Any help, please.


public function is_unique($str, $field)
{
list($table, $field)=explode('.', $field);
$q = $this->CI->db->query("SHOW KEYS FROM $table WHERE Key_name = 'PRIMARY'")->row();
$primary_key = $q->Column_name;

if($this->CI->input->post($primary_key) > 0):
$query = $this->CI->db->limit(1)->get_where($table, array($field => $str,$primary_key.' !='=>$this->CI->input->post($primary_key)));
else:
$query = $this->CI->db->limit(1)->get_where($table, array($field => $str));
endif;

return $query->num_rows() === 0;
}


[b]Edited :[/b]

Those lines has worked fine, I've made mistake when post data. Thanks.

web-johnny
  • profile picture
  • Administrator
  • 1,166 posts

Posted 26 November 2012 - 12:21 PM

Guys whoever is intrested to find an external library for the functionality $crud->unique_fields you can check my answer at stackoverflow at: http://stackoverflow.com/questions/13537503/codeigniter-custom-is-unique-logical-key-validation-or-callback

edramirez
  • profile picture
  • Member

Posted 10 November 2013 - 15:27 PM

In ancient times, we didn't create tables with a separate id field like this:

 

id integer autoincrement

username  varchar(10)

password varchar(40)

with id as primary key

 

The way we did this was like this was to eliminate  the autoincrement field called id and assign the primary key to the username. In this way, we allowed the database to handle the validation and process the add or edit request if and only if the constraint requirements were met. I myself still do it this way, following the ancient normal form rules. By doing so, one need not enforce uniqueness in a field that isn't the primary key anyway.

 

Sometimes there is great wisdom in returning to the ancient ways and follow the path of the ancient ones. hehehe

 

Regards,

 

Ed Ramirez

 

P.S. Don't forget to click the Like button...  :rolleyes: