我想为cakephp3应用程序编写一个简单的Tagging-Plugin。所以我们假设我们有一个模型 books 和一个模型评论。对于每个模型,应该可以附加标签 - 只需添加行为(在插件中):1
。
我在数据库中创建了两个表:$this->addBehavior('Tag.Taggable')
。
表tagged_tags:
tags, tagged_tags
tagged_id是已标记实体的ID。它所属的信息模型在另一个表中。 表格标签:
id | tag_id | tagged_id |
1 | 1 | 1 |
2 | 2 | 1 |
显然,只有第一个标签属于一本书。
id | tag | model |
1 | book | App\Model\Table\BooksTable |
2 | nobook | App\Model\Table\ReviewsTable|
检索数据非常有效。但储蓄是一个问题:
错误:SQLSTATE [42S22]:找不到列:1054未知列 'where子句'中的'Tags.model'
SQL查询:
SELECT TaggedTags.id AS
class TaggableBehavior extends Behavior { // Some more code here public function __construct(Table $table, array $config = []) { parent::__construct($table, $config); $this->_table = $table; $this->_table->belongsToMany('Tag.Tags', [ 'joinTable' => 'tagged_tags', 'foreignKey' => 'tagged_id', 'targetForeignKey' => 'tag_id', 'conditions' => [ 'Tags.model' => get_class($this->_table); ] ]); } }
,TaggedTags.tagged_id ASTaggedTags__id
,TaggedTags.tag_id ASTaggedTags__tagged_id
FROM tagged_tags TaggedTags WHERE(tagged_id =:c0 AND Tags.model = :C1)
我不是那么害羞,为什么cakephp会在这里执行SELECT查询,而我真的不在乎。为什么此查询导致错误很明显。但我的错误在哪里?它与TaggedTags__tag_id
有关。如果没有这个,我可以保存数据(但不能说Tag不属于一本书)
编辑:一些其他信息
这是完整的sql语句,显示在调试工具包http://freetexthost.com/tc3s46nugi
中控制器代码:
'conditions' => ['Tags.model' => get_class($this->_table);
在行为中我有一些逻辑(复制/粘贴)形成书签教程
public function add()
{
$book = $this->Books->newEntity();
if ($this->request->is('post')) {
$book = $this->Books->patchEntity($book, $this->request->data);
if ($this->Books->save($book)) {
$this->Flash->success(__('The book has been saved.'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('The book could not be saved. Please, try again.'));
}
}
答案 0 :(得分:0)
如果您创建标签模型,您将进行简易标记插件,并与其他模型建立HABTM关系。
以下是简单指南。
add.ctp
省略多个选择标记字段,而是放置标记文本字段(例如,tagsinput)。添加一些jquery标记插件。添加新标记(关键字)时,它会立即通过jquery post方法存储在标记表中。如果关键字存在于tags表中,则不要再次存储它。
<强>行为强>
来自标记字段的beforeSave方法处理值。 如果用逗号分隔的值,你可以使用类似的东西(CakePHP 2):
public function beforeSave($options = array())
{
if(!empty($this->data['Article']['tagsinput'])) {
$tags = explode(',', $this->data['Article']['tagsinput']);
foreach ($tags as $tag) {
$tagKey = $this->Tag->find('first',array(
'recursive' => -1,
'fields' => array('id'),
'conditions' => array('Tag.name' => $tag)
));
$this->data['Tag']['Tag'][] = $tagKey['Tag']['id'];
}
}
return true;
}
这会创建HABTM关系并将这些值存储在表articles_tags。
中edit.ctp
创建逗号分隔值:
<?php
$extract_tags = Hash::extract($this->data['Tag'],'{n}.name');
$tags = implode(',', $extract_tags);
echo $this->Form->input('tagsinput',
array(
'id' => 'tags',
'div'=>true,
'label'=>__('Tags'),
'class'=>'form-control input-lg',
'placeholder'=>__('Add keywords here'),
'value' => $tags
)
);
?>