cakephp3:保存关联数据

时间:2015-09-16 15:16:44

标签: associations conditional-statements cakephp-3.0

我想为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 AS   TaggedTags__id,TaggedTags.tag_id AS TaggedTags__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.'));
        }
    }

1 个答案:

答案 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
                    )
                );
            ?>