开发者

CakePHP is updating when it should be inserting a HasAndBelongsToMany model

开发者 https://www.devze.com 2022-12-20 09:32 出处:网络
I have a small problem. I am making a site that has Tags and Questions. I have a Question model, Tag model, QuestionsTag model, everything fits together nicely. The user upon asking something puts the

I have a small problem. I am making a site that has Tags and Questions. I have a Question model, Tag model, QuestionsTag model, everything fits together nicely. The user upon asking something puts the tags in the field seperated by a space (foo bar baz) much like on stackoverflow.com.

Now, here is the code to check if a tag already exists or not and entering the tag into the database and the required associations:

    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
                       开发者_JS百科 */
                        $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;
                    }
;               }
            }
        }
    }

The problem is this, a Question has an id of 1 and I want it to have the tags with id of 1, 2, 3.

When the 2nd and 3rd save get called, Cake sees that in the questions_tags table is already a question with id 1, so it just updates the tag.

But this is not correct, as there should be many questions in that table with the same id, as they refer to different tags belonging to them.

So, is there a way to prevent this? Prevent the save method from UPDATEing?

Thank you!


This behavior isn't specific to HABTM relationships. You are calling the save() method inside of a loop. After the first save, an id value is set and each subsequent save call sees the id and assumes it's an update. Within a loop, you first need to call model->create() to reset an id value that may exist.

From the CakePHP Docs at http://book.cakephp.org/view/75/Saving-Your-Data:

When calling save in a loop, don't forget to call create().

In your case, it would look like this:

$this->QuestionsTag->create();
$this->QuestionsTag->save (array(
                        'question_id' => $this->Question->id,
                        'tag_id'      => $tagId
                    ));


Check out saveAll. You can make a single call to $this->Question->saveAll(), and it will save any associated data you supply as well. Note that with HABTM data, it will perform a DELETE for any questions_tags associated with that question_id, then perform an INSERT for all the tag_id's included with your data.


if you want to make sure, that a new entry (INSERT) is made rather then an update, you can set $this->create(); right in front of the save call. See http://book.cakephp.org/view/75/Saving-Your-Data (in the upper part of the page): When calling save in a loop, don't forget to call create().

0

精彩评论

暂无评论...
验证码 换一张
取 消