2

我有一个小问题。我正在制作一个有标签和问题的网站。我有一个 Question 模型、Tag 模型、QuestionsTag 模型,一切都很好地结合在一起。用户在询问某事时将标签放在由空格(foo bar baz)分隔的字段中,就像在 stackoverflow.com 上一样。

现在,这里是检查标签是否已经存在并将标签输入数据库和所需关联的代码:

    function create () {
        if (!empty($this->data)) {
            $this->data['Question']['user_id'] = 1;
            $question = $this->Question->save ($this->data);

            /**
            * Preverimo če se je vprašanje shranilo, če se je,
            * vprašanje označimo.
            */
            if ($question) {
                $tags = explode (' ', $this->data['Question']['tags']);
                foreach ($tags as $tag){
                    if (($tagId = $this->Tag->existsByName($tag)) != false) {
                        /**
                        * Značka že obstaja, torej samo povezemo trenuten
                        * id z vprašanjem
                        */
                        $this->QuestionsTag->save (array(
                            'question_id' => $this->Question->id,
                            'tag_id'      => $tagId
                        ));
                    }
                    else {
                        /**
                        * Značka še ne obstaja, jo ustvarimo!
                        */
                        $this->Tag->save (array(
                            'name' => $tag
                        ));

                        // Sedaj pa shranimo
                        $this->QuestionsTag->save(array(
                            'question_id' => $this->Question->id,
                            'tag_id'      => $this->Tag->id
                        ));
                        $this->Tag->id = false;
                    }
;               }
            }
        }
    }

问题是这样的,一个问题的 id 为 1,我希望它有 id 为 1、2、3 的标签。

当第二次和第三次保存被调用时,Cake 看到 questions_tags 表中已经有一个 id 为 1 的问题,所以它只是更新了标签。

但这是不正确的,因为该表中应该有许多具有相同 id 的问题,因为它们引用了属于它们的不同标签。

那么,有没有办法防止这种情况发生呢?防止保存方法更新?

谢谢!

4

3 回答 3

3

此行为并非特定于 HABTM 关系。您正在save()循环内调用该方法。第一次保存后,id会设置一个值,随后的每个保存调用都会看到 id 并假定它是更新。在循环中,您首先需要调用model->create()以重置可能存在的 id 值。

来自http://book.cakephp.org/view/75/Saving-Your-Data的 CakePHP 文档:

在循环中调用 save 时,不要忘记调用 create()。

在您的情况下,它看起来像这样:

$this->QuestionsTag->create();
$this->QuestionsTag->save (array(
                        'question_id' => $this->Question->id,
                        'tag_id'      => $tagId
                    ));
于 2010-02-15T15:00:55.917 回答
0

查看saveAll。您可以对 进行一次调用$this->Question->saveAll(),它也会保存您提供的任何相关数据。请注意,对于 HABTM 数据,它将对与 that 关联DELETE的任何' 执行 a ,然后对包含在您的数据中的所有' 执行 a 。questions_tagsquestion_idINSERTtag_id

于 2010-02-15T14:04:21.360 回答
0

如果您想确保创建一个新条目 (INSERT) 而不是更新,您可以$this->create();在 save 调用之前进行设置。请参阅http://book.cakephp.org/view/75/Saving-Your-Data(在页面上部):在循环中调用 save 时,不要忘记调用 create()。

于 2010-02-15T15:00:37.433 回答