Pagination of query ignoring the LIMIT clause in CakePHP 3.x - cakephp

I am trying to create a query that would only return 2 results, and by following the documentation I get the query to run, however the limit is still set to 20 by default.
Here is how the query is built:
$upcomingMeetings = $this->Meetings->find('all')
->where(['Meetings.user_id' => $this->Auth->User('user_id')])
->andWhere(["Meetings.date >= " => date('Y-m-d') ])
->order(['Meetings.date' => 'ASC'])
->limit(2);
The result is being passed to the view like following:
$this->set('upcomingMeetings', $this->paginate($upcomingMeetings));
Here is the query that is being run on the database:
SELECT
Meetings.id AS `Meetings__id`,
Meetings.date AS `Meetings__date`,
Meetings.user_id AS `Meetings__user_id`,
FROM
meetings Meetings
WHERE
(
Meetings.group_id = 7
AND Meetings.date >= '2016-01-14'
)
ORDER BY
Meetings.date ASC
LIMIT
20 OFFSET 0
Any help or guidance is much appreciated.

When paginating a Query object, CakePHP will ignore the limit() clause and use the value defined in the $paginate configuration array instead.
This is what can be concluded after inspecting the source code.
Try adding the following to your controller:
public $paginate = [
'limit' => 2,
];

Related

How to dump the query in Phalcon Framework using Model

$content = Content::findFirst([
'conditions' => 'state = :state: AND URLid = :url: AND city = :city:',
'bind' => [
'state' => $geodata_usstates->statecode,
'url' => $company,
'city' => $geodata_geocity->city
]
]);
I want to dump the query generated for this. If I were using Laravel, I would simply do
$content->toSql();
But here I'm using Phalcon. How can I achieve the same thing in Phalcon?
Query is not available in your model. Query is build based on model using query builder, passed to Query instance and executed against your db connection.
What you could do is use the events manager and read using the db:beforeQuery event
Example here https://forum.phalconphp.com/discussion/18371/check-the-connection-before-querying-into-database
I don't believe you can output the complete query, because it's a prepared query - thus the best you'd get is:
SELECT * FROM `content` WHERE state = ? AND URLid = ? AND city = ? LIMIT 1
Personally, I don't bother trying to log queries in code. I've enabled the query log on my MariaDB server, and just check the log. The query logged is guaranteed to be the query run.

CakePHP 3.x Contains GroupBy

I am attempting to do a GroupBy on an associated table via contains -> conditions, however I am getting the following error...
Error: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'group = 'BrandUsers.user_id' AND BrandUsers.brand_id in (1,2,3,4,5,6))' at line 1
with the following query
SELECT
BrandUsers.id AS `BrandUsers__id`,
BrandUsers.user_id AS `BrandUsers__user_id`,
BrandUsers.brand_id AS `BrandUsers__brand_id`,
Users.id AS `Users__id`,
Users.username AS `Users__username`,
Users.email AS `Users__email`,
Users.password AS `Users__password`,
Users.first_name AS `Users__first_name`,
Users.last_name AS `Users__last_name`,
Users.token AS `Users__token`,
Users.token_expires AS `Users__token_expires`,
Users.api_token AS `Users__api_token`,
Users.activation_date AS `Users__activation_date`,
Users.secret AS `Users__secret`,
Users.secret_verified AS `Users__secret_verified`,
Users.tos_date AS `Users__tos_date`,
Users.active AS `Users__active`,
Users.is_superuser AS `Users__is_superuser`,
Users.role AS `Users__role`,
Users.created AS `Users__created`,
Users.modified AS `Users__modified`
FROM
brand_users BrandUsers
INNER JOIN
users Users
ON Users.id =
(
BrandUsers.user_id
)
WHERE
(
group = :c0
AND BrandUsers.brand_id in
(
:c1,
:c2,
:c3,
:c4,
:c5,
:c6
)
)
I have taken a look at the following links, but the above error persists
Group By within contain cakephp
cakephp GROUP BY within containable
Here is my code
$this->paginate = [
'contain' => [
'BrandUsers' => [
'conditions' => [
'group' => 'BrandUsers.user_id'
]
],
'BrandUsers.Users'
]
];
$brands = $this->paginate(
$this->Brands
->find('all')
->where(['Brands.user_id' => $this->Auth->user('id')])
);
As mentioned in the answers/comments to the questions that you've linked, there is no group option for containments, that's true for CakePHP 2.x as well as 3.x, and if there was such an option you would have placed it wrong, as you've nested it inside the conditions option, hence it is being compiled into the queries WHERE clause.
If you need to modify the query used for obtaining containments on the fly, then you can for example pass a callable as known from other query builder methods:
'BrandUsers' => function (\Cake\ORM\Query $query) {
return $query->group('BrandUsers.user_id');
}
or use the finder option to point to a finder that modifies the passed query accordingly:
'BrandUsers' => [
'finder' => 'groupedByUser'
]
It should be noted that grouping only works for HasMany and BelongsToMany associations, as they are not being joined into the main/parent query.
See also
Cookbook > Database Access & ORM > Query Builder > Passing Conditions to Contain
Cookbook > Database Access & ORM > Retrieving Data & Results Sets > Custom Finder Methods

Cakephp How to use SQL month function in cakephp find method

I have a query like
SELECT count(id),DATE_FORMAT(created,'%M') from searches group by month(created)
The output that I got like
count(id) DATE_FORMAT(created,'%M')
16 August
2 September
I applied this query in cakephp find method like below
$total = $this->Searches->find('count',[
'fields'=>['Searches.id',DATE_FORMAT('created','%M')],
'group' =>[month('Searches.created')]
]);
1st I am getting error date_format() expects parameter 1. How can I apply my top sql query in cakephp find method ?
I am using cakephp 3 version.
The query builder has a func() method that allows you to use SQL functions.
http://book.cakephp.org/3.0/en/orm/query-builder.html#using-sql-functions
$time = $query->func()->date_format([
'created' => 'identifier',
"'%M'" => 'literal'
]);
You can then use that $time variable in your query.

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.

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

Resources