Hi all.

I'm trying to get my head around HABTM associations with extra fields
in the join table, but without much success.

So, its confessional debugging time :-) I'm using latest stable
release of Cake 1.2.6.

Here's what I have so far...

My understanding is that if I want to use additional fields in the
join table (PostsTag), I have to specify the HABTM relationship by
hand:

class Post extends AppModel {

        var $hasMany = array(
                "PostsTag"
        );

}

class Tag extends AppModel {

        var $hasMany = array(
                "PostsTag"
        );

}

class PostsTag extends AppModel {

        var $belongsTo = array(
                "Post",
                "Tag"
        );

}

My Post data entry form looks like this (form.ctp):

<?php echo $form->create("Post", array("action"=>$this->action)) ?>
<?php echo $form->input("Post.id") ?>
<?php echo $form->input("Post.name") ?>
<?php echo $form->input("PostsTag.0.tag_id")?>
<?php echo $form->input("PostsTag.0.weight")?>
<?php echo $form->end("Submit") ?>

<?php echo pr($this->data) ?>

My add method in the posts controller looks like this:

        function add() {

                if (!empty($this->data)) {

                        if ($this->Post->saveAll($this->data)) {

                                $this->Session->setFlash("Saved");

                        }
                        else {

                                $this->Session->setFlash("Error");

                        }
                }

                $this->_populateLookups();

                $this->render("form");

        }


_populateLookups() is a helper function that sets the view variable to
populate the drop down for tags:

        function _populateLookups() {

                $tags = $this->Post->PostsTag->Tag->find("list");

                $this->set(compact("tags"));

        }

The edit action in PostsController looks like this:

        function edit($id) {

                if (!empty($this->data)) {

                        if ($this->Post->saveAll($this->data)) {

                                $this->Session->setFlash("Saved");

                        }
                        else {

                                $this->Session->setFlash("Error");

                        }
                }
                else {

                        $this->data = $this->Post->read(null, $id);

                }

                $this->_populateLookups();

                $this->render("form");

        }

Adding a new post and tagging it with a weight works fine.

However, updating an existing post creates duplicate key violations
(their is a unique key on post_id, tag_id in the posts_tags model)
because cake doesn't remove the join table rows as it does if you use
$hasAndBelongsToMany

Now, I could add some code before $this->Post->save($this->data) to
remove any PostsTag with the same post_id, but what if the save()
fails? All the habtm join data will have been lost :-(

How do I get cake to remove the join table data when it saves the post
like it does when you use a hasAndBelongsToMany relationship in the
model?

tbh, this information should be in the cake book (there's a request in
the comments of the habtm pages for it). Once I have a satisfactory
answer I'll add it :-)

Check out the new CakePHP Questions site http://cakeqs.org and help others with 
their CakePHP related questions.

You received this message because you are subscribed to the Google Groups 
"CakePHP" group.
To post to this group, send email to cake-php@googlegroups.com
To unsubscribe from this group, send email to
cake-php+unsubscr...@googlegroups.com For more options, visit this group at 
http://groups.google.com/group/cake-php?hl=en

Reply via email to