So, now the data is saving, I've come up with another issue:
Validation.

I've added some validation to the join table to ensure the weight
field is populated:

class PostsTag extends AppModel {

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

        var $validate = array(
                "weight"=>array(
                        "number"=>array(
                                "rule"=>"numeric",
                                "message"=>"must be a number"
                        ),
                        "required"=>array(
                                "rule"=>array("minLength", 1),
                                "message"=>"cannot be blank"
                        )
                )
        );

}

When the form is submitted and the validation fails, the save() fails
as expected but the error message from the join table is not
propagated and the form does not display the error message (it just
displayed the "Error" flash message. The validationErrors array in the
view is empty.

Is this a bug? I see that Mark Story has been doing some work on
something related (
http://cakephp.lighthouseapp.com/projects/42648/tickets/65-additional-fields-on-habtm-join-tables-wont-get-properly-validated
) and my version of CakePHP has his changes incorporated.


On Feb 15, 5:42 pm, "rich...@home" <richardath...@gmail.com> wrote:
> 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