I have the following code in my projects controller's index action
I achieved it via custom queries
1- it is good to use custom queries?
2- how can I write the following queries using cakephp functions joins contains etc
3- which method will be good?
my tables are as below
portfolio_projects [id,name,....,user_id,job_id,manymore_id]
portfolio_images [id,project_id,image,orders,status,.....]
portfolio_tags [id,tag,....]
portfolio_project_tags[id,project_id,tag_id]
and query is as below. I did this to fetch only needed data that is projects with its images and tags but not project's (user,job and others)
there are other tables linked to tags, images tables too but I do not need that data here.
$this->Project->recursive = -1;
$projects = $this->Project->find('all',array(
'conditions' => array(
'Project.user_id' => $this->Auth->user('id')
)
));
foreach($projects as $key=>$project)
{
//fetching project related tags starts here
$q="select * from portfolio_project_tags where 0";
$q="select tag.id as id,tag.tag from portfolio_project_tags as p left outer join portfolio_tags as tag on p.tag_id=tag.id where p.project_id=".$project['Project']['id'];
$tags = $this->Project->query($q);
$projects[$key]['Project']['tags']=$tags;
//fetching project related tags ends here
//fetching project related images starts here
$q2="select * from portfolio_images where 0";
$q2="select img.id as id,img.title as title, img.image as image from portfolio_images as img where img.project_id=".$project['Project']['id']." and img.status='Publish' order by orders";
$snaps = $this->Project->query($q2);
$projects[$key]['Project']['snaps']=$snaps;
//fetching project related images ends here
}
$this->set('projects',$projects);
You have 3 possibilities (at least) to retrieve data from a join table in CakePHP, that you should consider in the following order:
In your example, only the q1
request need a join because the q2
can be express as:
$this->PorfolioImage->find('all', array(
'fields' => array('PortfolioImage.id, PortfolioImage.title, PortfolioImage.image'),
'conditions' => array(
'PortfolioImage.project_id' => $project['Project']['id']
)
));
In your Project
model, you could add information to the related models, such as:
class Model extends AppModel {
public $actAs = array('Containable');
public $hasMany = array('PortfolioImage');
public $belongsTo = array('PortfolioTag') ;
}
Then, when you retrieve a Project
, you have access to the related PortfolioImage
and Tag
, for example:
debug($this->Project->read(null, 1)) ;
Would output:
Array(
'Project' => array(
'id' => 1,
/* other fields */
),
'PortfolioTag' => array(
'id' => /* */,
'tag' => /* */
),
'PortfolioImage' => array(
0 => array(
'id' => /* */,
/* other fields */
),
1 => array(/* */)
)
)
You just need to be carefull on the naming of foreign key, the CakePHP documentation about relationship is really easy to read.
You can do a join
query in CakePHP find
method:
$this->Project->find('first', array(
'fields' => array('Tag.id', 'Tag.title'),
'joins' => array(
'table' => 'portfolio_tags,
'alias' => 'PortfolioTag',
'type' => 'LEFT OUTER',
'conditions' => array('PortfolioTag.id = Project.tag_id')
)
)) ;
I'm really not used to CakePHP join
queries (the Containable
behaviour is often sufficient), but you'll find lot of information in the CakePHP documentation.
You should really not use custom queries except if you really know what you're doing because you have to take query of almost anything (sql injection at first place). At least, when doing custom queries, use Prepared Statements (see information at the end of this link ).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.