我正在尝试搜索,对具有特定标记或标记的帖子使用分页(例如,如果用户要选择两个标记,则会返回包含任一标记的帖子。)
我在帖子表格中定义了关系
public $hasAndBelongsToMany = array('Tags' => array(
'className' => 'Tags',
'joinTable' => 'posts_tags',
'foreignKey' => 'post_id',
'associationForeignKey' => 'tag_id',
'unique' => 'keepExisting'));
如何使用“查找”检索具有给定标记的行(名称或ID可以正常)
尝试:
// other pagination settings goes here
$this->paginate['conditions']['Tags.id'] = 13;
给我一个关系不存在的错误。
查看调试信息时,表格似乎没有加入Posts_Tags和Tags表,但是,当我调试数据到视图时,Posts对象包含标签数据。
我能找到的大多数文档似乎都围绕着CakePHP的早期版本,任何帮助都会受到赞赏。
答案 0 :(得分:3)
我自己找不到令人满意的解决方案。 我创建了一个处理此问题的行为。
创建一个名为HabtmBehavior.php的文件并将其放在app / Model / Behavior文件夹中。 将代码块放在那里并保存文件。
将行为添加到模型中:例如public $ actsAs = array('Habtm');
以下是find的使用示例。
<?php $this->Entry->find('all', array('habtm'=>array('Tag'=>array('Tag.title'=>'value to find'))) ?>
Paginate看起来像这样:
$this->paginate['Entry']['habtm']['Tag'] = array('Tag.title'=>'value to find');
您可以通过在habtm数组中添加其他模型名称来自由添加任意数量的关系。 (注意不要让它变得复杂,因为这可能会减慢你的查找结果。)
<?php
class HabtmBehavior extends ModelBehavior {
public function beforeFind(Model $model, $options) {
if (!isset($options['joins'])) {
$options['joins'] = array();
}
if (!isset($options['habtm'])) {
return $options;
}
$habtm = $options['habtm'];
unset($options['habtm']);
foreach($habtm as $m => $scope){
$assoc = $model->hasAndBelongsToMany[$m];
$bind = "{$assoc['with']}.{$assoc['foreignKey']} = {$model->alias}.{$model->primaryKey}";
$options['joins'][] = array(
'table' => $assoc['joinTable'],
'alias' => $assoc['with'],
'type' => 'inner',
'foreignKey' => false,
'conditions'=> array($bind)
);
$bind = $m.'.'.$model->{$m}->primaryKey.' = ';
$bind .= "{$assoc['with']}.{$assoc['associationForeignKey']}";
$options['joins'][] = array(
'table' => $model->{$m}->table,
'alias' => $m,
'type' => 'inner',
'foreignKey' => false,
'conditions'=> array($bind) + (array)$scope,
);
}
return $options;
}
}
希望这会有所帮助。 快乐的烘烤。
答案 1 :(得分:1)
我认为最好的解决方案是在连接表Model上应用find函数。我之前尝试过,它的工作正常。
在PostTag模型中:
/**
* @see Model::$actsAs
*/
public $actsAs = array(
'Containable',
);
/**
* @see Model::$belongsTo
*/
public $belongsTo = array(
'Post' => array(
'className' => 'Post',
'foreignKey' => 'post_id',
),
'Tags' => array(
'className' => 'Tag',
'foreignKey' => 'tag_id',
),
);
在您的控制器中:
// $tagsId = tags ids
$posts = $this->PostTag->find('all', array('conditions' => array('PostTag.tag_id' => $tagsId),'contain' => array('Post')));
如果你有标签(复数),post_tags(第一个单数第二复数),帖子(复数)表你必须有Tag,PostTag,Post Models。