Notes on CakePHP HABTM (Part 2, saving data)

If you haven’t read part 1, where I cover some HABTM basics, you should probably take a look at that article as well.

Part 2. Saving data

The next topic I wanted to cover is how to go about saving the HABTM data. Actually it is really not that complicated, as most of the work is taken care of for you.
Probably the most important thing is to make sure that your data arrives in the correct format for the save() method. The rest is really pretty easily handled by cake.

So let’s take a look at a few examples (still using our Post HABTM Tag)…

First, we’ve got a case where we know a Post ID and we are creating a single, new tag for it. We’d like to save the tag name and have CakePHP automagically associate it with a given post.

The form would look something like this:

echo $form->create('Tag');
echo $form->input('tag');
echo $form->input('Post.id', array('type'=>'hidden', 'value'=>5));
echo $form->end('Add tag');

And the controller action would be:

function add() {
$this->Tag->save($this->data);
}

Let’s also take a look at our data:

Array
(
    [Tag] => Array
        (
            [tag] => new one
        )

    [Post] => Array
        (
            [id] => 5
        )

)

To clear things up quickly, CakePHP will insert the new tag, grab the ID of the last insert and save the ID of the known post plus the ID of the newly created tag into the join table.

Now, let’s say you need to associate that same tag with a few different posts. Well, the only thing you need to do is to, again, make sure that you have correct fields in your form… so:

echo $form->create('Tag');
echo $form->input('tag');
echo $form->input('Post.1', array('type'=>'hidden', 'value'=>5));
echo $form->input('Post.2', array('type'=>'hidden', 'value'=>6));
echo $form->input('Post.3', array('type'=>'hidden', 'value'=>7));
echo $form->end('Add tag');

Will produce a data array that looks like:

Array
(
    [Tag] => Array
        (
            [tag] => my brand new tag
        )

    [Post] => Array
        (
            [1] => 5
            [2] => 6
            [3] => 7
        )

)

Basically this will save a new tag and associate that newly created tag with posts, which happen to have ID’s 5,6 and 7. I should mention that in the previous example the field could be named Post.1 instead of Post.id, but I find that ‘id’ is more descriptive and works just as well.

Also, in the example I’m using a hidden field with a given value for the ID, in the real life it would probably be a few checkboxes, with values for ID’s.

And lastly it’s worth to note that the above can be reversed, just as well you could setup a quick form to create a new Post and associate some known tags with it.

P.S. Be sure to check out Habtamable behavior, which helps to avoid some of the pain when working with HABTM models.

Related Posts

%d bloggers like this: