Would recursive=-1 help in case of find("list") in cakephp. I mean any performance benefit
With the default
$this->Post->find('list');
CakePHP make this query:
SELECT `Post`.`id`, `Post`.`name` FROM `posts` AS `Post` WHERE 1 = 1
No recursive query, so changing that command will not improve the query
No, recursive=-1 will not help full in case of $this->Model->find('list').
If you want to find('all') or find('first') , then it will be more use full.
eg. User , VatInfo , VatInfoLog are three models then
1) recursive=-1
$this->VatInfo->find('all')
Will return only VatInfo table data.
2) recursive=0
$this->VatInfo->find('all')
Will return $belongsTo User And VatInfo 2 tables data.
3) recursive=1
$this->VatInfo->find('all')
Will return $belongsTo User ,$hasMany VatInfoLog And VatInfo 3 tables data.
Try it!
In debug mode Cake shows you the running time of each query. Try both ways and see if anything changes. My guess is no, since it's only taking data from one table anyway for list queries.
Related
I've got a very complex query and trying to give a simple example of one of the sub-tables I'm having problems with, if you need more information or context please let me know.
I've posed a CSV file with some sample data here:
https://drive.google.com/open?id=0B4xdnV0LFZI1dzE5S29QSFhQSmM
We make cakes, and 99% of our cakes are made by us. The 1% is when we have a cake delivered to us from a subcontractor and we 'Receive' and 'Audit' it.
What I wanted to do was to write something like this:
SELECT
Cake.Cake
Instruction.Cake_Instruction_Key
Steps
FROM
Cake
Join Instruction
ON Cake.Cake_Key = Instruction.Cake_Key
JOIN Steps
ON Instruction.Step_Key = Steps.Step_Key
WHERE
MIN(Steps.Step_Key) = 1
This fails because you can't have an aggregate in the WHERE clause.
The desired results would be:
Cake C 13 Receive
Cake C 14 Audit
Cake D 15 Receive
Cake D 16 Audit
Thank you in advance for your help!
Take a look at the HAVING keyword:
https://msdn.microsoft.com/en-us/library/ms180199.aspx
It works more or less the same as the WHERE clause but for aggregate functions after the GROUP BY clause.
Beware however this can be slow. You should try filtering down the number of records as much as possible in the WHERE and even consider using a tempory table to aggregate the data into first.
What you're talking about is the GROUP BY/HAVING clause, so in your case you would need to add something like
GROUP BY Cake.Cake, Instruction.Cake_Instruction_Key, Steps
HAVING MIN(Steps.Step_Key) = 1
I have a Table A related many to many with a Table B and I want to know how many related rows I have in B with a given A entity.
In SQL it would be something like this:
SELECT COUNT(*) FROM AB WHERE A_id=1;
I thought that I should place it in the model of A with a Virtual Field that retrieves the count, but I didnĀ“t find a way to use the model itself to get the related B rows.
I tried with
$this->contain(['B'])->count()
But it didn't work because 'contain' is undefined. So, how should I get the count?
Make sure that u put the association in both of your models initialize method and dont call contain() on $this.
$query = $this->A->find();
numberOfRecords = $query->contain(['B'])->count;
I currently have a users table and a posts table. My posts table has a field for user_id, however, I am not sure how I would grab the users name field which is in the users table. I was thinking of using the models afterFind() method and then using SQL to select the data, but there has to be a better way than this. Also, on my view action, I am using the read() function to grab a single post. Would the models afterFind() kick in after it runs read()? If not, is there an equivalent such as afterRead()?
Just make an association of Post belongsTo User, and every regular find/read operation that has a sufficiently high recursive value will automatically fetch the user with each post.
$post = $this->Post->find(...);
echo $post['User']['name'];
you have to go like below :
$this->Cake->findById(7); Cake.id = 7
here , you can you use your user_id instead of 7 like..
Find BY CAKE PHP
$this->Post->bindModel(array('belongsTo'=>'User'));
$post = $this->Post->findById($post_id);
$userName = $post['User']['name'];
Here are errors, I've typed it in eclipse (:
Is getLastInsertID and Model->id same? And which one can happen concurrency problem ?
$this->Model->save($this->data);
__thisFunctionTakesAVeryLongTimeToExecute(); //function 1
$insertId = $this->Model->getLastInsertId();
Does getLastInsertId() return the ID from the data I've saved 2 lines above. Or does it return the latest ID that's created?
I mean
what happen if when the function 1 (__thisFunctionTakesAVeryLongTimeToExecute();) execute another user do an another save. then which id will i get?
$this->Model->id
Is used to set an id and read or modify data related.
$this->Model->getLastInsertID();
Return the id of the last inserted row in this model.
For your last question, make a test ! And publish your answer here.
I have another similar problem.
If I put
$oid = $this->Home->Order->getLastInsertID();
$order = $this->Home->Order->find('first',array('conditions'=>array( 'Order.id'=>$oid)));
the model associations between Order and its hasMany tables are destroyed.
If I put
$oid = 1; // for example
$order = $this->Home->Order->find('first',array('conditions'=>array( 'Order.id'=>$oid)));
the model associations are maintained!!!!
Use below code for cakePHP 3.0 or above
$result = $this->ModelName->save($data)
echo $result->id;
I just inherited some cakePHP code and I am not very familiar with it (or any other php/serverside language). I need to set the id of the item I am adding to the database to be the value of the last item plus one, originally I did a call like this:
$id = $this->Project->find('count') + 1;
but this seems to add about 8 seconds to my page loading (which seems weird because the database only has about 400 items) but that is another problem. For now I need a faster way to find the id of the last item in the database, is there a way using find to quickly retrieve the last item in a given table?
That's a very bad approach on setting the id.
You do know that, for example, MySQL supports auto-increment for INT-fields and therefore will set the id automatically for you?
The suggested functions getLastInsertId and getInsertId will only work after an insert and not always.
I also can't understand that your call adds 8 seconds to your siteload. If I do such a call on my table (which also has around 400 records) the call itself only needs a few milliseconds. There is no delay the user would notice.
I think there might be a problem with your database-setup as this seems very unlikely.
Also please have a look if your database supports auto-increment (I can't imagine that's not possible) as this would be the easiest way of adding your wanted functionality.
I would try
$id = $this->Project->getLastInsertID();
$id++;
The method can be found in cake/libs/model/model.php in line 2768
As well as on this SO page
Cheers!
If you are looking for the cakePHP3 solution to this you simply use last().
ie:
use Cake\ORM\TableRegistry;
....
$myrecordstable=Tableregistry::get('Myrecords');
$myrecords=$myrecordstable->find()->last();
$lastId = $myrecords->id;
....