Cakephp find method produces weird SQL - cakephp

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' )

Related

Convert query from SQL to 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();

CakePHP Find Condition does not appear in SQL Query

My Find conditions don't seem to be making their way into the SQL based on Debugkits SQL log. Can someone point out to me what I'm doing wrong? This is my first time trying to filter my Find results.
BillingCenters controller
$conditions = array(
'BillingCenter.isactive' => '1'
);
$this->set(
'billingcenters',
$this->BillingCenter->find('all', array($conditions))
);
The resulting SQL Query shown by DebugKit is.. (missing the WHERE clause???)
SELECT
`BillingCenter`.`id`,
`BillingCenter`.`startdate`,
`BillingCenter`.`enddate`,
`BillingCenter`.`name`,
`BillingCenter`.`isactive`,
`BillingCenter`.`created`,
`BillingCenter`.`modified`
FROM
`bm`.`billing_centers` AS `BillingCenter`
WHERE
1 = 1
If i changed the controller code to
$this->set(
'billingcenters',
$this->BillingCenter->find('all')
);
The resulting SQL is STILL the same.
SELECT
`BillingCenter`.`id`,
`BillingCenter`.`startdate`,
`BillingCenter`.`enddate`,
`BillingCenter`.`name`,
`BillingCenter`.`isactive`,
`BillingCenter`.`created`,
`BillingCenter`.`modified`
FROM
`bm`.`billing_centers` AS `BillingCenter`
WHERE
1 = 1
This bites me all the time.
Change your find line to this:
$this->set(
'billingcenters',
$this->BillingCenter->find('all', array('conditions' => $conditions))
);

how using SQL IN operator in find method of cakephp ORM

i am beginner in cakephp , and i want use SQL IN operator in find method , i have words table.
my code is :
$this->Word->find('Word.wordid in (83,82)');
, and this code create this query :
SELECT `Userword`.`userwordid`, `Userword`.`userid`, `Userword`.`wordid`,
`Userword`.`date`, `Userword`.`levelid` FROM `userwords` AS `Userword` WHERE
`Userword`.`wordid` = (82)
but i need this query
SELECT `Userword`.`userwordid`, `Userword`.`userid`, `Userword`.`wordid`,
Userword`.`date`, `Userword`.`levelid` FROM `userwords` AS `Userword` WHERE
`Userword`.`wordid` IN (83,82)
how can getting like this query (using IN operator )
thanks.
you need to let cake take care of that - simply use it as it was a string (but make sure it is an array):
$arrayOfIds = [1, 5, ...];
$this->Word->find('all', array(
'conditions' => array('Word.wordid' => $arrayOfIds)
));

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')));

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