cakephp 3 query is not executing - php

I am new in cakephp3. I am trying to execute below query but its showing me error.
$lifeinsurances = TableRegistry::get('LifeInsurances')->find("all");
$life_insurances = $lifeinsurances->find()
->join([
'table' => 'institutions',
'alias' => 'institutions',
'type' => 'LEFT',
'conditions' => 'institutions.id = LifeInsurances.institute_id',
]);
I have fixed previous query. Now I am getting only one table data.
EDIT
Now I created association using cake bake. But a new error showing this time. Below is my code.
public function index() {
$this->paginate = [
'contain' => ['Institutions']
];
$lifeInsurances = $this->paginate($this->LifeInsurances);
$this->set(compact('lifeInsurances'));
$this->set('_serialize', ['lifeInsurances']);
}
Internal server error
if I remove
$this->paginate = [
'contain' => ['Institutions']
];
$lifeInsurances = $this->paginate($this->LifeInsurances);
error stop showing

If you have your table associations set up correctly (which they should be automatically if you used bake to create your code), you should be able to simply say:
$lifeinsurances = TableRegistry::get('LifeInsurances')
->find('all')
->contain(['Institutions']);

If you want contain to work , you need to define associations in your respective Models (lies in Table Folder in case of cakephp 3.x).
Since you are saying that you have baked the models, Ensure that relationships are defined in the respective models.
That may be the reason that it is throwing error.
Normally when you have created all the tables in your database , then you should bake the models. Because adding table after you have baked the models do not define relationships in the new models and you have to explicitly define it.
Have a look at this -
How associations get defined when code is baked in Cakephp
Also check the naming conventions of the foreign keys defined in the tables. Cakephp use this naming conventions to define the relationships between models.
Furthermore it would be great if you can post the error log, so as to find out more exact solution to your problem.

Related

cakephp 4.x query to get results from database

I came across a problem recently that I have to make a find(all) query in cakephp.
Problem is I was unable to call model function to cakephp controller & add a command in function that would allow me to make a find(all) function in cakephp and retrieve all rows in a database that I was looking for.
I would like to make a simple query to make a call to database table that is in database that retrieves rows in table that are matching query.
public function display(){
$query = $HouseParty->find('all', [
'conditions' => ['HouseParty.popular >' => 0],
'contain' => ['title', 'image', 'popular'],
'limit' => 6
]);
$results = $query->all();
var_dump($results);
}
Also what is code to make call to model in Cakephp Controller. So controller knows that we are making calls to models from controller. So we can interact with models from controller because I intend to make multiple calls to different models from same controller in future. Please be helpful looking for a response been stuck on this problem for days just making a question here that is relevant & resourceful for others as well. I would like to make a question come handy to other community members I would just need to get code apart from what I have mentioned above that what code should I write in order to make a call for calling models in one controller - call to multiple models from one controller. Is the above code correct and is so what makes it from giving an error as below. So what is code to make calls to models from database.
Error i get is below:
Call to a member function find() on null
I think you should start with a simple query based on your model.
I will assume your model is HouseParties (a database table named house_parties).
Then in your HousePartiesController, you can query:
$query = $this->HouseParties->find('all', [
'conditions' => ['popular >' => 0],
'limit' => 6
]);
I think you may be misusing 'contain' as a select. 'contain' is for related tables, not fields in the table you are querying.
If you go through the CMS tutorial in full https://book.cakephp.org/4/en/tutorials-and-examples.html it should be clear.

Yii 'limit' on related model's scope

I have a model called Guesses that has_many Comments. I'm making eager queries to this to then pass on as JSON as response to an API call.
The relations are obviously set between the two models and they are correct(one2many <=> belongs2)
I added a scope to Comments called 'api' like this:
public function scopes()
{
return array(
'api' => array(
'select' => 'id, comment, date',
'limit'=>3,
'order'=>'date DESC',
'together'=>true,
),
);
}
And I'm running the following one-liner query:
$data = Guesses::model()->with('comments:api')->findAll();
The issue here is that when calling the 'api' scope using a with('relation'), the limit property simply doesn't apply.
I added the 'together'=>true there for another type of scope, plus I hear it might help. It doesn't make a difference.
I don't need all the comments of all Guesses. I want the top 3 (or 5). I am also trying to keep the one-liner call intact and simple, manage everything through scopes, relations and parameterized functions so that the API call itself is clean and simple.
Any advice?
There are several methods to achieve this, which i know.
1st. You can add limit to relation, for ex.
'photos' => array(self::HAS_MANY, 'Photo', 'companyId',
'limit'=>3
)
2nd. You can call limit results when call relation, for ex.
$model->photos(array('limit' => 4));
Maybe there are some other methods, but i don't know them.
According to the documentation, that should be ok..
My only suggestions would be:
$data = Guesses::model()->with(
array('comments'=>array('scopes'=>array('api')))
)->findAll();
or:
$data = Guesses::model()->findAll(array(
'with'=>array('comments'=>array('scopes'=>array('api')))
));
but that should be the same logic. I don't think together will help you.. it is true by default.
Update
These examples are taken straight from the relational documentation
$posts=Post::model()->with('comments:recently:approved')->findAll();
or since 1.1.7:
$posts=Post::model()->with(array(
'comments'=>array(
'scopes'=>array('recently','approved')
),
))->findAll();
or since 1.1.7
$posts=Post::model()->findAll(array(
'with'=>array(
'comments'=>array(
'scopes'=>array('recently','approved')
),
),
));
and lazy-loading:
$approvedComments = $post->comments('comments:approved');
Which suggests that your code should work.. what query is being run in your trace?
Do you have any default scopes that you haven't posted? Are their any extra options defined in your relation? I have had trouble with both of these interfering with named scopes.

cakephp - how to get the data from a model->model->model type relationship

I've got three models, Equipment which hasmany Booking, which in turn hasmany PaypalTransaction, and I'm trying to find PaypalTransactions which belong to the booking which belongs to the particular listing I'm dealing with, and which was created less than 1 day ago. All this in the Listings Controller
So in my Listings controller I have
$oneDayAgo = date('Y-m-d H:i:s', strtotime('-1 day'));
$toBeConfdBookings = $this->Equipment->Booking->PaypalTransaction->find('all', array('conditions' => array('PaypalTransaction.created' > $oneDayAgo)));
All the models have the appropriate relationships in them as created by cake bake but what ends up in $toBeConfdBookings is all wrong.
Anyone tell me what I'm doing wrong?
Simple answer:
You cannot run a find() on models three-deep like that. Instead, try just loading the model, then running the find():
$this->loadModel('PaypalTransaction');
$oneDayAgo = date('Y-m-d H:i:s', strtotime('-1 day'));
$toBeConfdBookings = $this->PaypalTransaction->find('all', array('conditions' => array('PaypalTransaction.created' > $oneDayAgo)));
(You can only run find()s on loaded models or models that are directly related to a loaded model.)
Answer for how I first interpreted your question:
Normally when you want to pull related results, it's VERY simple - just use CakePHP's Containable Behavior.
What you're trying to do, however, is to get the related model data AND limit the results based on a related model. So, because Containable creates separate queries, you cannot limit based on related models - in that case, you'll need to utilize joins.
Code Example:
$oneDayAgo = date('Y-m-d H:i:s', strtotime('-1 day'));
$this->loadModel('Booking'); // if neccessary
$paypalTransactions = $this->Booking->find('all', array(
'conditions' => array(
'Booking.equipment_id' => $equipmentId
),
'contain' => array(
'Equipment'
),
'joins' => array(
array('table' => 'paypal_transactions',
'alias' => 'PaypalTransaction',
'type' => 'INNER',
'conditions' => array(
'PaypalTransaction.booking_id = Booking.id',
"PaypalTransaction.created > '".$oneDayAgo."'"
)
)
));
The above code basically reads:
The find: find all Bookings that are owned by $equipmentId
The contain: also retrieve the data for the associated Equipment (optional)
The join: limit the results of the Bookings and Paypal Transactions to only those where the transaction occurred after one day ago (and retrieve the transaction data too)
The way you have it now you are basically just calling the PaypalTransaction model and request its find to return you all transactions in the last day.
$this->FirstModel->SecondModel->ThirdModel doesn't mean to connect results from the first model to the second and then to the third, it's only a way to help you load the linked model instead of using $this->loadModel('ThirdModel') to load it.
So you still need to place conditions according to what you want to do. For example, if it was just one model linked (assuming $this->Booking is set to a record) you could do:
$this->Booking->PaypalTransaction->find('all', array(
'conditions' => array(
'PaypalTransaction.created >' => $oneDayAgo,
'PaypalTransaction.booking_id => $this->Booking->id
)
);
You can't extend this to 2 extra models unless your third model contains keys for both previous models which I doubt it does (and probably shouldn't).
CakePHP will autobind models in find conditions for belongsTo and hasOne associations, and for the rest 2 types you need to be joining your tables.
It is a little bit of extra work but you get used to it quickly.
When dealing with deeper associations i think you should look at this link. You can retrieve data from tables by bindModel.
http://mark-story.com/posts/view/using-bindmodel-to-get-to-deep-relations

CakePHP HABTM Filtering

I've got two tables - users and servers, and for the HABTM relationship, users_servers. Users HABTM servers and vice versa.
I'm trying to find a way for Cake to select the servers that a user is assigned to.
I'm trying things like $this->User->Server->find('all'); which just returns all the servers, regardless of whether they belong to the user.
$this->User->Server->find('all', array('conditions' => array('Server.user_id' => 1))) just gives an unknown column SQL error.
I'm sure I'm missing something obvious but just need someone to point me in the right direction.
Thanks!
Your table names are right. There are many ways to do this:
Use the Containable behavior
In your AppModel, set the following:
var $recursive = -1;
var $actsAs = array('Containable');
Then, use the following code to query your servers:
$userWithServers = $this->User->find('all', array(
'conditions' => array('User.id' => 1),
'contain' => array('Server')
));
Note that we are querying the User model, instead of the Server model to accomplish this.
Use bindModel
$this->Server->bindModel(array('hasOne' => array('UsersServer')));
$this->Server->find('all', array(
'fields' => array('Server.*'),
'conditions' => array('Server.user_id' => 1)
));
I personally don't recommend using bindModel a lot. Eventually, your code becomes a bit unmanagable. You should try using the Containable behavior whenever possible. The code looks cleaner and simpler. More on the bindModel method can be found here.
HTH.
I think you're supposed to name tour table user_servers.

adding hasMany association causes find() to not work well

OK, I am a little bit lost...
I am pretty new to PHP, and I am trying to use CakePHP for my web-site.
My DB is composed of two tables:
users with user_id, name columns
copies with copy_id, copy_name, user_id (as foreign key to users) columns.
and I have the matching CakePHP elements:
User and Copy as a model
UserController as controller
I don't use a view since I just send the json from the controller.
I have added hasMany relation between the user model and the copy model see below.
var $hasMany = array(
'Copy' => array(
'className' => 'Friendship',
'foreignKey' => 'user_id'
)
);
Without the association every find() query on the users table works well, but after adding the hasMany to the model, the same find() queries on the users stop working (print_r doesn't show anything), and every find() query I am applying on the Copy model
$copy = $this->User->Copy->find('all', array(
'condition' => array('Copy.user_id' => '2')
));
ignores the condition part and just return the whole data base.
How can I debug the code execution? When I add debug($var) nothing happens.
I'm not an expert, but you can start with the following tips:
Try to follow the CakePHP database naming conventions. You don't have to, but it's so much easier to let the automagic happen... Change the primary keys in your tabel to 'id', e.g. users.user_is --> users.id, copies.copy_id -->copies.id.
Define a view, just for the sake of debugging. Pass whatever info from model to view with $this->set('users', $users); and display that in a <pre></pre> block
If this is your first php and/or CakePHP attempt, make sure you do at least the blog tutorial
Make CakePHP generate (bake) a working set of model/view/controllers for users and copies and examine the resulting code
There's good documentation about find: the multifunctional workhorseof all model data-retrieval functions
I think the main problem is this:
'condition' => array('Copy.user_id' => '2')
It should be "conditions".
Also, stick to the naming conventions. Thankfully Cake lets you override pretty much all its assumed names, but it's easier to just do what they expect by default.
The primary keys should be all named id
The controller should be pluralised: UsersController
First off, try as much as possible to follow CakePHP convention.
var $hasMany = array(
'Copy' => array(
'className' => 'Friendship',
'foreignKey' => 'user_id'
)
);
Your association name is 'Copy' which is a different table and model then on your classname, you have 'Friendship'.
Why not
var $hasMany = array(
'Copy' => array('className'=>'Copy')
);
or
var $hasMany = array(
'Friendship' => array('className'=>'Friendship')
);
or
var $hasMany = array(
'Copy' => array('className'=>'Copy'),
'Friendship' => array('className'=>'Friendship')
);
Also, check typo errors like conditions instead of condition
Your table name might be the problem too. I had a table named "Class" and that gave cake fits. I changed it to something like Myclass and it worked. Class was a reserved word and Copy might be one too.

Categories