我试图将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' => ''
),
);
}
<?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%'))
SQL Error: 1054: Unknown column 'Category.id' in 'where clause'
答案 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