有问题使用cakephp方法在cakephp中连接4个表

时间:2011-10-06 19:18:47

标签: php mysql cakephp

我试图将4张桌子加在一起,并且尝试这样做时遇到了极大的困难。这是四个表

Tables
-------------------

    users
    projects
    project_categories
    categories

Relationships
---------------------

    users hasMany projects
    projects hasMany project_categories
    project_categories belongsTo projects & categories
    categories hasMany project_categories

我可以将用户加入项目。但我不能为连接添加类别

用户

<?php
class User extends AppModel {
    var $name = 'User';
    var $displayField = 'username';
    //The Associations below have been created with all possible keys, those that are not needed can be removed

    var $hasMany = array(
        'Project' => array(
            'className' => 'Project',
            'foreignKey' => 'user_id',
            'dependent' => false,
            'conditions' => '',
            'fields' => '',
            'order' => '',
            'limit' => '',
            'offset' => '',
            'exclusive' => '',
            'finderQuery' => '',
            'counterQuery' => ''
        )
    );

}

项目模型

<?php
class Project extends AppModel {
    var $name = 'Project';
    var $displayField = 'project_title';
        var $actsAs = array('Containable');

    var $belongsTo = array(
        'User' => array(
            'className' => 'User',
            'conditions' => '',
            'fields' => '',
            'order' => ''
        ),
    );

        var $hasAndBelongsToMany = array(
            'Os' =>
                    array(
                        'className' => 'OperatingSystem',
                        'joinTable' => 'project_operating_systems',
                        'foreignKey' => 'project_id',
                        'associationForeignKey' => 'os_id',
                        'conditions' => '',
                        'fields' => '',
                        'order' => '',
                        'limit' => '',
                        'offset' => '',
                        'finderQuery' => '',
                        'deleteQuery' => '',
                        'insertQuery' => ''
            ),
            'Category' => array(
                    'className' => 'Category',
                    'joinTable' => 'project_categories',
                    'foreignKey' => 'project_id',
                    'associationForeignKey' => 'category_id',
                    'conditions' => '',
                    'fields' => '',
                    'order' => '',
                    'limit' => '',
                    'offset' => '',
                    'finderQuery' => '',
                    'deleteQuery' => '',
                    'insertQuery' => ''
            ),
        );
}

project_category

<?php
class ProjectCategory extends AppModel {
    var $name = 'ProjectCategory';
    var $displayField = 'id';

    //The Associations below have been created with all possible keys, those that are not needed can be removed

    var $belongsTo = array(
        'Project' => array(
            'className' => 'Project',
            'foreignKey' => 'project_id',
            'conditions' => '',
            'fields' => '',
            'order' => ''
        ),
        'Category' => array(
            'className' => 'Category',
            'foreignKey' => 'category_id',
            'conditions' => '',
            'fields' => '',
            'order' => ''
        )
    );
}

类别模型

<?php
class Category extends AppModel {
    var $name = 'Category';
    var $displayField = 'name';
        var $actsAs = array('Tree');

    var $belongsTo = array(
        'ParentCategory' => array(
            'className' => 'Category',
            'conditions' => '',
                        'foreignKey' => 'parent_id',
            'fields' => '',
            'order' => ''
        ),
    );

    var $hasAndBelongsToMany = array(
        'Project' => array(
                        'className' => 'Project',
                        'joinTable' => 'project_categories',
                        'foreignKey' => 'category_id',
                        'associationForeignKey' => 'project_id',
                        'conditions' => '',
                        'fields' => '',
                        'order' => '',
                        'limit' => '',
                        'offset' => '',
                        'finderQuery' => '',
                        'deleteQuery' => '',
                        'insertQuery' => ''
        ),
    );
}

是我的控制器请求

<?php
class ProjectsController extends AppController {

    var $name = 'Projects';

        function search()
        {
            if (!empty($this->data)):

                $keywords = Array();
                $keywords['categories'] = array();

                $categories = $this->data['Project']['ProjectCategory'];
                if($categories):
                    foreach($categories as $category):
                        $keywords['categories'][] = $category;
                    endforeach;
                endif;

                $queries = str_replace(",", " ",$this->data['Project']['query']);
                $keywords['project_title'] = explode(" ", $queries);

                $nq = '';

                foreach($keywords as $key =>$value)
                {
                    if($key == 'project_title'):
                        foreach($value as $q):
                            $nq[] = array('Project.project_title LIKE'=>"%$q%");
                        endforeach;
                    elseif($key == 'categories'):
                        foreach($value as $q):
                            $nq[] = array('Category.id'=>"$q");
                        endforeach;
                    endif;
                }

                $final = array("OR"=>$nq);
                $joins = '';//array('table'=>'users','alias'=>'User','type' => 'LEFT','conditions'=>'User.id = Project.user_id'); 
                $options = array('conditions'=>$final);
                debug($options);


                $projects = $this->Project->find('all',$options);
                $this->set('projects',$projects);
                $this->paginate();

            endif;
        }
}

我的查询看起来像这样

SELECT `Project`.`id`, `Project`.`user_id`, `Project`.`status`, `Project`.`approval_status`, `Project`.`approval_date`, `Project`.`project_title`, `Project`.`project_type`, `Project`.`budget`, `Project`.`bidding_type`, `Project`.`esl`, `Project`.`country`, `Project`.`secrecy`, `Project`.`secrecy_file`, `Project`.`os`, `Project`.`description`, `Project`.`perfomance`, `Project`.`cme`, `Project`.`files_share`, `Project`.`delivery`, `Project`.`delivery_days`, `Project`.`delivery_due`, `Project`.`legal`, `Project`.`close`, `Project`.`agree`, `Project`.`created`, `Project`.`favorite`, `Project`.`top_employer`, `Project`.`view_counter` FROM `projects` AS `Project` WHERE ((`Category`.`id` = 2) OR (`Category`.`id` = 3) OR (`Category`.`id` = 4) OR (`Category`.`id` = 5) OR (`Category`.`id` = 6) OR (`Project`.`project_title` LIKE '%money%'))

ERROR

 SQL Error: 1054: Unknown column 'Category.id' in 'where clause'

1 个答案:

答案 0 :(得分:0)

你有没有理由Project hasAndBelongsToMany Category? 但请尝试在项目模型中设置Project belongsTo User

var $belongsTo = 'User';

OR

var $belongsTo = array(
      'User' => array(
            'className' => 'User',
            'foreignKey' => 'user_id'
      )
); 

修改

除了不需要$ belongsTo的project_categories之外,我现在看不到模型关系中的问题。只需$ name即可。

现在有了HABTM条件的诀窍是设置一个hasOne过滤器,一个动态绑定。

$this->Project->bindModel(array(
      'hasOne' => array(
            'ProjectCategory',
            'FilterCategory' => array(
            'className' => 'Category',
            'foreignKey' => false,
            'conditions' => array(
                  'FilterCategory.id = ProjectCategory.tag_id'
            )
      )
)));

$this->Project->find('all', array(
      'fields' => array('Project.*'),
      'conditions'=>array('FilterCategory.id' => array($ids))
));

你不应该这样做:

(`Category`.`id` = 2) OR (`Category`.`id` = 3) OR (`Category`.`id` = 4) OR (`Category`.`id` = 5)

您可以将每个或那些放在“OR”中,同时可以将所有ID保存在数组中并执行'Category.id' => $ids

它会做

`Category`.`id` IN (2, 3, 4, 5)

在查询中。


所以这个:

                foreach($keywords as $key =>$value)
                {
                    if($key == 'project_title'):
                        foreach($value as $q):
                            $nq[] = array('Project.project_title LIKE'=>"%$q%");
                        endforeach;
                    elseif($key == 'categories'):
                        foreach($value as $q):
                            $nq[] = array('Category.id'=>"$q");
                        endforeach;
                    endif;
                }

                $final = array("OR"=>$nq);
                $joins = '';//array('table'=>'users','alias'=>'User','type' => 'LEFT','conditions'=>'User.id = Project.user_id'); 
                $options = array('conditions'=>$final);
                $projects = $this->Project->find('all',$options);

会变成:

            $ids = array();
            foreach($keywords as $key =>$value)
            {
                if($key == 'project_title'):
                    foreach($value as $q):
                        $nq[] = array('Project.project_title LIKE'=>"%$q%");
                    endforeach;
                elseif($key == 'categories'):
                    foreach($value as $q):
                        $ids[] = $q;
                    endforeach;
                endif;
            }

            $nq[] = array('Category.id'=>$ids);

            $final = array("OR"=>$nq);
            $this->Project->bindModel(array(
                  'hasOne' => array(
                        'ProjectCategory',
                        'FilterCategory' => array(
                        'className' => 'Category',
                        'foreignKey' => false,
                        'conditions' => array(
                              'FilterCategory.id = ProjectCategory.tag_id'
                        )
                  )
            )));

            $this->Project->find('all', array(
                  'fields' => array('Project.*'),
                  'conditions'=>$final)
            ));

我建议您阅读http://book.cakephp.org/view/1039/Associations-Linking-Models-Together