Convert query from SQL to cakephp - cakephp

I have a SQL query like:
SELECT a,b,c
from 'table '
where a like '$ae%' and b = '$b'.
Here $a is a numeric field.
I need to write the above query in below form:
$abc = ClassRegistry::init('Model Name')->find('list', array('fields' => array('a,', 'b'), 'conditions' => array('b' => array($b),'a LIKE'=>'$a%'),));

I suggest you to go and read the documentation.
Also remember to always cite the exact cake version, and if you have some error, show that error in your question.
Anyway, since you did show some kind of effort, here the way to do that query using cake3:
first of all don't use find('list') unless you actually want a key, value array. But since you want 3 fields use find('all') or simply find()
$query = $yourTable->find()
->select(['a', 'b', 'c')
->where([
'b' => $b,
'a LIKE' =>"%$a%"
]);
then if you want an array you have to call toArray() on the query.
$result = $query->toArray();

Related

cakephp - order by timestamp DESC not working

I have a table called posts that stores all the posts . It has two columns "Created" and "Modified" .
Below is my query in the model :
$options = [
'conditions' => [
'circle_id' => $my_circle_list,
'team_id' => $this->current_team_id,
'modified BETWEEN ? AND ?' => [$start, $end],
],
'order' => ['modified'=> 'desc'],
'limit' => $limit,
'fields' => ['post_id'],
];
$res = $this->find('list', $options);
Now i want the latest edited posts on top and below is what my mysql dump reads like :
SELECT `Post`.`id` FROM `db`.`posts` AS `Post` WHERE `Post`.`id` IN (125, 124) AND `Post`.`del_flg` = '0' ORDER BY `Post`.`modified` desc LIMIT 20
If i run this query in my database editor ,it gives my the correct output , but in my controller the ordering changes again , this is something i figured after i debugged the array values.
Would be helpful if anyone could tell me if there's any specific reason behind this . The call to this model method from the controller is done in a conventional manner .
When using $this->find() after Cake has queried the database with the generated SQL it calls the afterFind() method on the model where it can manipulate the data. This is the mostly likely place for the ordering to have been modified.

Cakephp insert sql statement

I'd like to insert data into a mysql table using 'the cakephp way'.
I have a multi-stage program that stores data to a session, and toward the end of the program I'd like to write the session data to the database. I could do this using a standard sql insert statement but would like to know how this should be done using cakephp. (Most of the cakephp doc discusses sending data from a webform, and I'd like to manually submit session data.)
Should I manually format the session data in this format and then send this to the model? And if so, is there a helper function for this?
Array
(
[ModelName] => Array
(
[fieldname1] => 'value'
[fieldname2] => 'value'
)
)
Yes, that's the way to do it. There's really no need for a helper function, just use the ones you normally would.
$name = 'Foo';
$city = 'Bar';
$this->ModelName->save(
array(
'name' => $name,
'city' => $city
)
);

whats wrong with this query

I have this in my table model called Table
$test = $this->find('first', array(
'conditions' => array('table.test_id is NULL'),
'order'=> array('table.created ASC'),
)
);
it doesnt work. Tryingt to get the latest row with some criteria
Well, first of all, to get the latest row, you would want to organize by the created field descending, rather than ascending. Also, there are some problems with your syntax, that I have cleaned up below.
$this->find('first', array('conditions'=>array('Table.test_id'=>NULL), 'order'=>array('Table.created'=>'desc')));

Cakephp find method produces weird SQL

I'm trying to do a Cakephp Find query, and I'm having a little where clausule:
$pending = $this->Transaction->find('all', array('conditions' => array('Transaction.amount >' => 'Transaction.recieved')));
I'd expect it would generate something like this:
SELECT * From `transactions` as `Transaction` WHERE `Transaction`.`amount` > `Transaction`.`recieved`
However, it's producing the following SQL:
SELECT * From `transactions` as `Transaction` WHERE `Transaction`.`amount` > 'Transaction.recieved'
Notice the small difference between
`Transaction`.`recieved`
and
'Transaction.recieved'
Why is this? My SQL query is failing now.
Cake has no way of knowing that you didn't intend to use a string (i.e. it's syntactically identical to for example array( 'Transaction.name' => 'foo' )). It works if you give the condition as a single string:
'conditions' => array( 'Transaction.amount > Transaction.received' )

How to use OR Condition in Paginate function in Cakephp?

I am facing a problem while fetching values using paginate function in cakephp. In the "to" field of message I have CSV fields of userid. To search messages for a single user. I am using the code below...
$this->set('message', $this->paginate('Message', array(
'or'=> array(
"Message.to LIKE" => "".$this->Session->read('Auth.User.id').",",
"Message.to LIKE" => ",".$this->Session->read('Auth.User.id').","
)
)));
But the query is formed in this manner which is not what I want.. I want to two conditions with OR condition.
SELECT `Message`.`id`, `Message`.`timestamp`, `Message`.`to`, `Message`.`from`,
`Message`.`message`, `Message`.`subject`, `Message`.`urgent`, `Message`.`read`,
`Message`.`tag`, `Message`.`open`, `Message`.`reply_id`, `User`.`id`,
`User`.`fname`, `User`.`lname`, `User`.`user`, `User`.`password`,
`User`.`photo`, `User`.`created`, `User`.`access`, `User`.`login`,
`User`.`status`, `User`.`role`
FROM `messages` AS `Message`
LEFT JOIN `users` AS `User` ON (`Message`.`to` = `User`.`id`)
WHERE `Message`.`to` LIKE ',1,'
ORDER BY `Message`.`timestamp` desc
LIMIT 5
The problem is that your conditions array stumbles across a PHP limitation: an array can not have two keys with the same name.
'or'=> array(
"Message.to LIKE" => "".$this->Session->read('Auth.User.id').",",
"Message.to LIKE" => ",".$this->Session->read('Auth.User.id').","
)
You are using the key "Message.to LIKE" twice, so only the last one gets used.
The workaround looks like this:
'or'=> array(
array("Message.to LIKE" => $this->Session->read('Auth.User.id') . ","),
array("Message.to LIKE" => "," . $this->Session->read('Auth.User.id') . ",")
)
Oh, and you should seriously think about a) database normalization and b) code readability.
I think part of the problem might be that he is using LIKE with only the literal exact match syntax.
If any of the following assumptions are incorrect then ignore this..
But it seems like you are searching for user#domain.tld in the to string and having to attach an 'or' condition to match the case where the recipient is listed as a single email address in a string of comma separated email addresses...
I don't think cake adds the '%' character to LIKE queries automagically so perhaps you could try adding it to the query. This should make it match both cases with a single condition in the find call.
<?php
... snip ...
'conditions' => array(
"Message.to LIKE" => "%" . $this->Session->read( 'Auth.User.id' ) . "%"
),
... snip ...
?>
Just make the condition into an array
$this->set('message', $this->paginate('Message', array(
"Message.to LIKE" => array("".$this->Session->read('Auth.User.id').",",",".$this->Session->read('Auth.User.id').",")
)));

Resources