inner join not working in cakephp - php

i have two tables in my database salaries model is Salary and userdetais model is Userdetail in which i want to fetch result bye comparing id and user_id code is
$this->Salary->find('all',
array(
'joins'=>array(
'table'=>'erp_userdetails',
'alias' => 'Userdetail',
'type' => 'INNER',
'conditions' => array('Salary.user_id' => 'userdetail.id')
)
)
);

Try this
this->Salary->find('all',
array('joins'=>
array(
array('table'=>'erp_userdetails',
'alias' => 'Userdetail',
'type' => 'INNER',
'conditions' => array('Salary.user_id' => 'userdetail.id')
)
)
)
);

You can use cakephp relational model.
Add belongsTo relation on Salary model
public $belongsTo=array(
"Userdetail"=>array(
"foreignKey"=>"user_id"
)
)

Related

Cakephp join query Belongs to

hello I have three tables in my database. Country, State,and City. In state table there is a country_id as foreign key and in city table there is state_id as foreign key. The problem is I want to get the country name when I am querying in the city table. I'll share the code so you can fully understand
Country.php
class Country extends AppModel{
public $useTable = 'countries';
}
State.php
class City extends AppModel{
public $useTable = 'cities';
public $belongsTo = array(
'State' => array(
'className' => 'State',
'foreignKey' => 'state_id',
'fields' => array('state.id','state.name')
)
);
}
City
class State extends AppModel{
public $useTable = 'states';
public $belongsTo = array(
'Country' => array(
'className' => 'Country',
'foreignKey' => 'country_id',
'fields' => array('Country.id','Country.name','Country.short_name')
)
);
okay here is the code. If I use this query
$this->State->find('all', array(
'conditions' => array(
'state.country_id' => $country_id
),
I can get the country name from country table. same is the case If I do this in city table like this
$this->City->find('all', array(
'conditions' => array(
'city.state_id' => $state_id
),
I can get all the state names city names here. So Now in this same table in one query how I can get the country name as well ?
Try using the recursive property.
Setting $this->City->recursive = 2 gets associated data for the table and associated data on the associated tables.
$this->City->recursive = 2;
$this->City->find('all', array(
'conditions' => array(
'city.state_id' => $state_id
),
//other stuff you use in this find
));
You can also using the "joins" flag.
$this->City->find('all', array(
'conditions' => array(
'City.state_id' => $state_id
),
'joins' => array(
array(
'table' => 'states',
'alias' => 'State',
'type' => 'left',
'conditions' => 'State.id = City.state_id'
),
array(
'table' => 'countries',
'alias' => 'Country',
'type' => 'left',
'conditions' => 'Country.id = State.country_id'
)
),
'fields' => array('City.id', 'State.name', 'Country.name',
//include all the fields you need
)
));
See: http://book.cakephp.org/2.0/en/models/model-attributes.html#recursive
In addition to the first answer, make sure to contain the foreign key for the Country.
class City extends AppModel{
public $belongsTo = array(
'State' => array(
'className' => 'State',
'foreignKey' => 'state_id',
'fields' => array('State.id','State.name', 'State.country_id'), // Make sure to contain the foreign key for the `Country`.
)
);
}
For your information, you can also use ContainableBehavior instead of recursive.
http://book.cakephp.org/2.0/en/core-libraries/behaviors/containable.html

cakephp join and mysql join

UPDATED!
i am relativly new in cakephp but having experience with mysql and php.
The model look like:
Person->Father
Father is self refered to person.
I wrote the following based on mysql query which gives back the father of "1" person
mysql:
SELECT `Father`.name,`Father`.id from persons as `Father` left join persons as `Person` on `Person`.`father_id`=`Father`.`id` where `Person`.id=1
cakephp
$options = array(
'fields' => array(
//'Father.name',
'Father.id',
),
'joins' => array(
array(
'conditions' => array(
'Person.father_id = Father.id',
),
'table' => 'persons',
// 'alias' => 'Person', i commented because having conflict with scaffolded model
'type' => 'left',
),
),
'conditions' => array(
'Person.id' => '1',
),
'contain' => array(
'Person','Father',
),
);
$data = $this->Person->find('first', $options);
$fatherquery=$this->Person->find('first',array('conditions'=>array('Person.id'=>$data['Father']['id'])));
To get the same as mysql i have add this extra line(the last one $father=....,but now it seems subquery and look like the join isn't working) because of Father and Person are not the same model and if i have
$data['Father']['name'] and $data['Person']['name'] they are not equal
By the way i have a solution already,but maybe i misunderstand some concept.
Is there a way the get the mysql query easier?
Try this. (Notice the lack of a contain. The only reason to use contain is if you're not already getting the data in the main-model's find() or a join):
//Person model (cake 2.x code)
$this->find('first', array(
'fields' => array(
'Father.id',
'Father.name'
),
'conditions' => array(
'Person.id' => 1
),
'joins' => array(
array(
'table' => 'persons',
'alias' => 'Father',
'type' => 'left',
'conditions' => array(
'Person.father_id = Father.id'
)
)
)
));

How to set conditions for HABTM relation

In kid model i have defined this below HABTM relation.
public $hasAndBelongsToMany = array(
'Pics' => array(
'className' => 'Pic',
'joinTable' => 'pics_kids',
'foreignKey' => 'kid_id',
'associationForeignKey' => 'pic_id'
)
);
Pics table store details of pics like comment, pic_url and date and pics_kids table have pic_id and kid_id id's that relate pic and kids . If i have to retrieve record based on kid_id and date(date of pic in pics table) how to retrieve it?
$kid_pics=$this->kid->find('all', array(
'conditions' => array(
'kid.id' => 1,
'Pic.date' => '26/07/2014'
)
));
if i use above query i get error that no column Pic.date in where claue.
Add a condition to your HATBM relationship dynamically:
$this->Kid->hasAndBelongsToMany['Pic']['conditions'] = array(
'Pic.date' => '26/07/2014'
) ;
$kid_pics = $this->Kid->real(null, 1) ;
You can use built-in Containable Behavior
$this->Kid->Behaviors->load('Containable');
$kid_pics = $this->Kid->find('all', array(
'conditions' => array(
'Kid.id' => 1
),
'contain' => array(
'Pic' => array(
'conditions' => array(
'Pic.date' => '26/07/2014'
)
)
)
));

Display a field from a 3rd table

I am trying to display a field from a 3rd table in a relationship, and after checking posts here and the docs, I am still stuck.I have 3 models all related in some way. I have found similar posts here but I am still not getting it to work. I am learning so sorry if I have missed this somewhere in the docs but I have read a fair bit and have tried a lot. I am guessing too much now on this so I need help.
1)Tutorsession - belongsto teachers,
2) Teacher -has 1 user,hasmany tutorsessions
3) User- has 1 teacher, //////I want to display a field from this table given I display tutorsessions
In controller
$this->set('tutor',
$this->Tutorsession->find('first',
array(
'conditions' => array('Teacher.user_id' => $id),
'contain' => 'User.username'
)
)
); //////////no error but no results
from view echo '<td>'. $item['User']['username'].'</td>'; ///////error user undefined
The tutorsession automatically gets rows from teacher table but not user table witht he model setup on a findall.
I want to display a username from the user table. I display the tutorsession table , I then can display the teacher table with the model association but I cant go from the teacher table to the user table to get a user name from the user id as the common field. I have checked the docs below and I am not sure why my code isnt ble to display a username from users table.
http://book.cakephp.org/2.0/en/core-libraries/behaviors/containable.html
http://book.cakephp.org/2.0/en/models/retrieving-your-data.html
update: here are the models
class User extends AppModel {
public $hasOne = array(
'Teacher' => array(
'className' => 'Teacher',
'dependent' => true
)
class Tutorsession extends AppModel
{
public $name='Tutorsession';
public $belongsTo = array(
'Teacher' => array(
'className' => 'Teacher',
'foreignKey' => 'teacher_id'
)
class Teacher extends AppModel
{
public $name='Teacher';
public $hasMany = array('Tutorsession');
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id'
)
);
Add containable behavior in your Model
public $actsAs = array('Containable');
Execute following query In controller
$contain = array('Teacher' => array('User'));
$this->set('tutor', $this->Tutorsession->find('first',array(
'conditions' => array('Teacher.user_id' => $id),
'contain' => $contain
)));
Try this:
$this->Tutorsession->recursive = 2;
$this->Tutorsession->Teacher->contain('User');
$this->set('tutor',
$this->Tutorsession->find('first',
array(
'conditions' => array('Teacher.user_id' => $id)
)
)
);
$tutor=$this->Teacher->find('first',
array(
'conditions' => array('Teacher.user_id' => $id)
)
);
debug($tutor); exit();
Your result similar:
'Teacher' => array(
'id' => '1',
'name' => 'abc',
'created' => '1397040385',
'updated' => '1397725860'
),
'User' => array(
'id' => '4',
'name' => 'administrators',
'created' => '1397032953',
'modified' => '1397032953'
),
'Tutorsession' => array(
0=>array(
'id' => '3',
'name'=>'abc',
'created' => '1400729137'
),
1=>array(
'id' => '4',
'name'=>'abc',
'created' => '1400729137'
)
)
Ensure your models are correct

CakePHP: How to retrieve data from two tables using an inner join?

I have two tables in a database, one as user(id,first_name,last_name), and the other one as location(id,country).
I need to perform an inner join with these two tables based on the condition user.id = location.id, and the query result should contain the columns first_name, last_name and country.
I have tried the following query in CakePHP:
$this->set('users', $this->User->find('list', array(
'fields' => array(
'User.id',
'User.first_name',
'location.country'
),
array(
'joins' => array(
array(
'table' => 'location',
'alias' => 'location',
'type' => 'INNER',
'conditions' => array('User.id = location.id')
)
)
)
)));
which however produces this error:
Unknown column 'location.country' in 'field list'
What could be the problem?
I think your syntax is wrong because the options array should have a key for the joins. You appear to have an extra array. Try:
$this->set('users',$this->User->find('list',
array(
'fields' => array('User.id', 'User.first_name','location.country'),
'joins' => array(array('table' => 'location',
'alias' => 'location',
'type' => 'INNER',
'conditions' => array('User.id = location.id')
))
)
));

Categories