I have a users table, a role_members table and a roles table.
The role_members table has a user_id and a role_id because users can have many roles.
I have a DataTable that has user id, email, name, and roles in it. I can easily sort and filter based on the fields in the users table. The way the DataTable works, there is one search box that searches all fields. So, my search query needs to be an ‘OR’ where username like search_term OR email like search_term OR role_name like search_term
The problem arises when I try to sort or filter based on the Role names. If I want to sort by RoleMember.Role.name or search by RoleMember.Role.name how do I do so?
My find options are as follows:
$sOrder = array('User.full_name' => 'asc');
if (isset($params['iSortCol_0'])) {
$sOrder = array();
for ( $i=0 ; $i<intval( $params['iSortingCols'] ) ; $i++ )
{
if ( $params[ 'bSortable_'.intval($params['iSortCol_'.$i]) ] == "true" )
{
$sOrder[$columns[ intval( $params['iSortCol_'.$i] ) ]] = $params['sSortDir_'.$i] ;
}
}
}
$find_options = array(
'order' => $sOrder,
'contain' => array(
'RoleMember' => array('Role', 'Instance'),
'AllowedLocation'
),
'limit' => $limit,
'offset' => $offset
);
if(isset($params['sSearch'])){
$search_term = '%'. $params['sSearch'] .'%';
$find_options['conditions'] = array(
'Or' => array(
'User.full_name LIKE ' => $search_term,
'User.email LIKE ' => $search_term,
'User.username LIKE ' => $search_term
//'RoleMember.Role.name LIKE ' => $search_term,
)
);
}
Joins will definitely work but it will be very inefficient if you do not cache your query... Now try this-
$options['joins'] = array(
array(
'table' => 'role_members',
'alias' => 'RoleMember',
'type' => 'INNER',
'conditions' => array(
'RoleMember.user_id = User.id'
)
),
array(
'table' => 'roles',
'alias' => 'Role',
'type' => 'INNER',
'conditions' => array(
'RoleMember.role_id = Role.id'
)
)
); // here we join all the tables, so all fields are available to place conditions...
$options['conditions'] = array(
'OR' => array(
'User.full_name LIKE ' => $search_term,
'User.email LIKE ' => $search_term,
'User.username LIKE ' => $search_term
'Role.name LIKE ' => $search_term,
)
);
$users = $this->User->find('all', $options);