CakePHP在应该插入HasAndBelongsToMany模型时正在更新

时间:2010-02-15 14:00:15

标签: cakephp has-and-belongs-to-many

我有一个小问题。我正在建立一个包含标签和问题的网站。我有一个问题模型,标签模型,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,因为它们引用了属于它们的不同标签。

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

谢谢!

3 个答案:

答案 0 :(得分: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
                    ));

答案 1 :(得分:0)

结帐saveAll。您可以拨打$this->Question->saveAll()一次,它也会保存您提供的所有相关数据。请注意,对于HABTM数据,它会为与DELETE相关联的任何questions_tags执行question_id,然后对包含的所有INSERT执行tag_id与您的数据。

答案 2 :(得分:0)

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