Reputation: 1975
I'm looking for a way to use Active Record in CodeIgniter to build my query.
My current code is this:
$this->db-> like('responsible', $user->id);
$this->db->or_like('accountable', $user->id);
$this->db->or_like('consulted', $user->id);
$this->db->or_like('informed', $user->id);
// Get the tasks, but only with the correct start or end date
$tasks = $this->db->get_where('level_' . $this->config->item('answer_level'), array('date_end' => $offset, 'ccode' => $user->country));
// Check if tasks exist
if($tasks->num_rows() > 0){
// Tasks have been found that should have been finished!
echo $tasks->num_rows() . " tasks found for " . $user->first_name . " that should have been finished!\n";
$last_month_tasks = $tasks->result();
}
unset($tasks);
Which produces the following SQL:
SELECT *
FROM (`level_3`)
WHERE `date_start` = -5
AND `ccode` = 'GB'
AND `responsible` LIKE '%5%'
OR `accountable` LIKE '%5%'
OR `consulted` LIKE '%5%'
OR `informed` LIKE '%5%'
But I need it to produce this SQL:
SELECT *
FROM (`level_3`)
WHERE `date_start` = -5
AND `ccode` = 'GB'
AND (
`responsible` LIKE '%5%'
OR `accountable` LIKE '%5%'
OR `consulted` LIKE '%5%'
OR `informed` LIKE '%5%'
)
Upvotes: 2
Views: 701
Reputation: 47894
CodeIgniter ABSOLUTELY DOES support nesting of queries and clauses. In this case, the solution is to encapsulate the set of LIKE conditions in parentheses using group_start()
and group_end()
.
I do want to warn that if the user ids are integers, it is rarely appropriate to use LIKE conditions because this would make the query vulnerable to over-matching substrings of a larger user id. In other words, 12
would match 12
, 112
, 121
, 122
, 123
, etc. Something about your coding intention is giving me code-smell concerns.
or_like()
is capable of receiving an associative array where the keys are the columns to be searched and the values are the values to be searched.
select('*')
does not need to be explicitly written, it is implied when omited.
The from()
clause and where()
conditions can be consolidated into the get_where()
call which is an extension to get()
which is necessary to actually execute the query. (I see that you are already doing this, I'm just explaining to readers.)
Model methods shouldn't be doing any echoing -- they should, at most, return data. Counting the results and validating the data can be done in another layer. Simply return the payload to the calling method.
return $this->db
->group_start()
->or_like([
'responsible' => $user->id,
'accountable' => $user->id,
'consulted' => $user->id,
'informed' => $user->id,
])
->group_end()
->get_where(
'level_' . $this->config->item('answer_level'),
[
'date_end' => $offset,
'ccode' => $user->country,
]
)
->result();
Upvotes: 0
Reputation: 3242
CodeIgniter's ActiveRecord does not support nesting of queries and clauses. You have to do it manually like this:
$this->db->select('*');
$this->db->from('level_' . $this->config->item('answer_level'));
$this->db->where(array('date_end' => $offset, 'ccode' => $user->country));
$this->db->where("(responsible LIKE '%5%' OR accountable LIKE '%5%' OR consulted LIKE '%5%' OR informed LIKE '%5%')");
$tasks = $this->db->get();
Upvotes: 3