简体   繁体   中英

cakephp convert custom query to cakephp query

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:

  1. Containable Behaviour
  2. CakePHP join query
  3. Custom query

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']
    )
));

The containable behaviour

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.

CakePHP join query

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.

Custom queries

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM