Retrieve data from associated database in cakephp - cakephp

I have an Entries table with users_id as a foreign key to the Users table.
I have set the belongsTo association in the EntriesTable like so:
$this->belongsTo('Users', [
'foreignKey' => 'user_id',
'joinType' => 'INNER'
]);
After that I wrote this in the EntriesController:
$entries = TableRegistry::get('Entries');
$query = $entries->findByTitle($title)
->contain(['Users']);
$entry = $query->first();
$this->set('entry', $entry);
In the VIEW template of the Entries I have to show the username field of the user that wrote the Entry.
I am aware that in previous versions of CakePHP 1, I could just write $entry['User']['username'] to retrieve the username of the User who wrote the Entry. Now that I am using CakePHP 3.6, it doesn't seem to work. How do I perform the same task in CakePHP 3?

You can write like below
In controller
public function view($title)
{
$entry = $this->Entries->findByTitle($title)->contain(['Users']);
$entry = $entry->first();
$this->set('entry', $entry);
}
OR
public function view($title)
{
$query = $this->Entries->find('all', [
'where' => ['Entries.title' => $title],
'contain' => ['Users']
]);
$entry = $query->first();
$this->set('entry', $entry);
}
In view
<?= $entry->user->username ?>

So in cakephp you were loading Model of its controller, which is done as default,you can directly create an find() method in same controller,if you want to find from other table/ model you can do is-
a. $this->Entries->otherTableName()->find()->all();
b. $tableName= $this->loadModel('tableName');
$tableName->find();

Related

Cakephp 3.5 - Entity - Virtual Field not showing

I have defined in an entity this :
protected $_virtual = [ 'full_name' ];
protected function _getFullName()
{
return( $this->_properties['firstname'] . ' ' . $this->_properties['lastname'] );
}
But the full_name field is not retrieved by any query ( paginator or find('all') ) ... when the table is referred as an associated table.
The main table is GenPersons.
In that case, the field is showed correctly.
But then the I make
$this->paginate = [ 'contain' => ['GenPersons'] ]
from the AerPilots controller ( AerPilots is a model ) ; and try to get the field as
$aerPilot->gen_person->full_name;
nothing is showed.
Am I forgetting something ?
I found it.
The problem was in the association on the model.
The GenPersons table belongs to General plugin.
The AerPilots table belongs to Aeronautical plugin.
When I baked the model for AerPilots, it generated this code :
$this->belongsTo('GenPersons', [
'foreignKey' => 'gen_person_id',
'className' => '**Aeronautical**.GenPersons'
]);
And it must be :
$this->belongsTo('GenPersons', [
'foreignKey' => 'gen_person_id',
'className' => '**General**.GenPersons'
]);

How to use cakephp find list to retrieve two different field from different Model?

I want to display a drop-down list of the list of student name with its value, student_user_id. But the problem is student name is stored in a different model which is hard to align together in find('list'), a find function of Cakephp.
I have some code of the model project that already joins tables. When I code the getStudentList, it does not know the User.user_display_user field.
Model
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => false,
'conditions' => array('User.user_id = Project.student_user_id')
)
);
function getStudentList()
{
$entry = $this->find('list',array('fields' => array('Project.student_user_id','User.user_display_name')));
return $entry;
}
So: How I can handle this issue?
You should use containable behavior and tell CakePHP that in this case you want to join those two tables:
$entry = $this->find('list', array(
'fields' => array('Project.student_user_id', 'User.user_display_name'),
'contain' => array('User')
));
By default joins should not be made until specifically requested - for performance reasons.
See http://book.cakephp.org/2.0/en/core-libraries/behaviors/containable.html
Note:
$recursive = 0 would also work but is discouraged to use.

How to use custom MySQL queries in CakePHP?

I am working on cakephp now.Please explain the process of custom mysql query in cake php.
we have to write query by using
$this->Model->query();
and I return this to controller.In controller,i loaded the model in particular function and i called the function and set that function to view like this
$this->set('post',$this->User->get());
is it correct process?please explain the code ...
What query do you want to write this way? It is possible to write nearly all queries using the CakePHP ORM. Using the query building functions of CakePHP is the prefered way of doing it.
All data fetching an manipulation should be done in a model as well. See Separation of Concerns.
Here is a complete model method to fetch an user record based on its id OR slug.
public function view($userId, $options = []) {
$defaults = array(
'contain' => array(),
'conditions' => array(
'OR' => array(
$this->alias . '.' . $this->primaryKey => $userId,
$this->alias . '.slug' => $userId,
),
$this->alias . '.email_verified' => 1
),
);
$result = $this->find('first', Hash::merge($defaults, $options));
if (empty($result)) {
throw new NotFoundException(__d('user_tools', 'User not found!'));
}
return $result;
}
Controller:
public function view($userId = null) {
$this->set('user', $this->User->view($userId);
}
Alternative but NOT preferred mode method to fetch te data
public function view($userId, $options = []) {
$result = $this->query(/* Your query here */);
if (empty($result)) {
throw new NotFoundException(__d('user_tools', 'User not found!'));
}
return $result;
}
Your solution is correct, let me eleborate it in more detail
1st Solution
In your controller
$arrayTemp =array();
$arrayTemp = $this->ModelName->query(' Your Query String ');
$this->set('post',$arrayTemp);
2nd Solution
In your model class
function returnDate(){
return $this->query('Your Query String')
}
In Controller class
$arrayTemp = $this->ModelName->returnDate();
$this->set('post',$arrayTemp);
}

Cakephp: Associations not working

I want to do a simple cakephp association program but it's not working.
I have two database tables: users and sec_datas. When i run this program it just shows the result of first row of users table, not the result of both tables which have same sec_id value.
Controller code:
<?php
class UsersController extends AppController
{
public function index()
{
$this->autoRender = FALSE;
$this->loadModel('User');
$storeDivisions = $this->User->find();
echo "<pre>";
print_r($storeDivisions);
echo "</pre>";
}
}
Model code:
<?php
class User extends AppModel {
public $useTable='users';
public $hasOne = array(
'Sec_data' => array(
'ClassName' => 'Sec_data',
'Conditions' => array('User.sec_id=Sec_data.sec_id'),
'Dependent' => false
)
);
}
?>
If the primary key of User model is id then cake try to associate the foreign key in Sec_data with that key regardless the conditions you set.
First of all you should do domething like
public $hasOne = array(
'Sec_data' => array(
'ClassName' => 'Sec_data',
'ForeignKey' => 'sec_id',
'Dependent' => false
)
);
But it would work only if sec_id is related to User.id
if you want Sec_data.sec_id related to User.sec_id (and User.sec_id is different from User.id) then you have to join the tables manually
edit: see comments
There are a couple of things going wrong here. You should read up on CakePHP's conventions.
Your associated model class should be called SecData, then it will automatically map to the sec_datas table.
No need to use loadModel.
No need to specify conditions. Set the correct recursive level instead.
For hasOne, only one table has a foreign key. By default, the other Model has it ("User hasOne SecData" -> SecData has foreign key). So in your example, you should remove the column sec_id from User, and add a user_id column to your SecData Model.
See also: CakePHP Book on associations
Updated Controller code:
<?php
class UsersController extends AppController {
public $uses = array('User'); // Do this instead of loadModel
public function index() {
$this->autoRender = FALSE;
$this->User->recursive = 1; // Make User load associated records
$storeDivisions = $this->User->find('all');
pr($storeDivisions); // pr() is a Cake shorthand for print_r wrapped in <pre>
}
}
For your model:
<?php
class User extends AppModel {
// Unecessary. Convention is to use lowercase classname + 's', which
// already gives us 'users'
// public $useTable='users';
public $hasOne = array(
'SecData' => array( // Model class Sec_Data must be renamed accordingly
'dependent' => false
)
);
}
?>
Study model association in cake php . Here is very good explanation http://www.phpsupercoder.com/model-association-cake-php

Can't Filter on Assosciated Model cakePHP

I have the following in my Usercontroller on my view function.
$this->User->recursive = 2;
$options = array('conditions' => array('User.' . $this->User->primaryKey => $id, 'Step.site_id' => $this->Auth->user('site_id')));
$this->set('user', $this->User->find('first', $options));
Its filter perfectly the the User model but its simply ignoring the Step.site_id part and errors saying the field does not exist.
Any pointers where I am going wrong? I am using cakephp 2.*
I have already read a view questions about using contain but I wasn't able to get it working correctly.
My guess - "Step" is not the proper alias for the hasMany relationship (You should share more information. This problem involves your model definitions and database table definitions)
Does this work?
$this->User->recursive = 2;
$options = array('conditions' => array('User.' . $this->User->primaryKey => $id, $this->User->Step->alias . '.site_id' => $this->Auth->user('site_id')));
$this->set('user', $this->User->find('first', $options));

Resources