0
votes

I have a CakePHP Add Photo View that is using optgroups so that the HABTM related Tag model's data is shown in grouped fashion in the view. In the Photo controller I send the related Tag model data as follows to get the optgroups grouping of Tags by Tag Category:

//fields shown to create optgroups eg group tags by category
$this->set('tags', $this->Photo->Tag->find('list', array(
    'fields' => array('Tag.id', 'Tag.tagname', 'Tag.category'),
    'conditions' => array(
        'Tag.account_id' => $this->Session->read('Auth.User.account_id')))));
}

The view shows the Tags nicely grouped by Category. So that part works perfectly.

However, after adding a new Photo and selecting one or more Tags to assign to it, it does save the Photo properly but not the assigned Tags.

I believe that CakePHP saveAll is expecting a data array as would be delivered without the optgroup Category > Tag hierarcy, and is therefore not saving Tag data when new Photo is added and Tags are assigned to the Photo.

What do I need to do to give it the proper array to save the related Tags? Will it be in the controller after Create() where I 'remove' the Category grouping?

A bit of background on this from CakePHP http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html

"If you would like to generate a select with optgroups, just pass data in hierarchical format. This works on multiple checkboxes and radio buttons too, but instead of optgroups wraps elements in fieldsets:"

$options = array(
    'Group 1' => array(
    'Value 1' => 'Label 1',
    'Value 2' => 'Label 2'
   ),
  'Group 2' => array(
  'Value 3' => 'Label 3'
  )
);
echo $this->Form->select('field', $options);

Output:

<select name="data[User][field]" id="UserField">
    <optgroup label="Group 1">
        <option value="Value 1">Label 1</option>
        <option value="Value 2">Label 2</option>
     </optgroup>
     <optgroup label="Group 2">
         <option value="Value 3">Label 3</option>
    </optgroup>
</select>
1

1 Answers

0
votes

Ok so this problem had nothing to do with the array structure.

It turns out I had 'Photo.Tag' instead of just 'Tag' in the Add Photo View. Here is the old Add Photo View code that didn't work:

    <div class="photos form">

        <p><?php echo $this->element('admin_nav'); ?></p>

    <?php echo $this->Form->create('Photo'); ?>
        <fieldset>
            <legend><?php echo __('Add Photo'); ?></legend>
        <?php
            echo $this->Form->input('account_id', array('type'=>'hidden'));
            //echo $this->Form->input('filename', array('type'=>'hidden'));
            echo $this->Form->input('filename', array('type' => 'file', 'label' => 'Upload photo'));
            echo $this->Form->input('desc');
            echo $this->Form->input('Photo.Tag' , array('label'=>'Tags', 'multiple'=>'checkbox'));

        ?>
        </fieldset>
    <?php echo $this->Form->end(__('Submit')); ?>
    </div>

Here is the new Add Photo View code which now saves the new photo with the tags selected:

    <div class="photos form">

        <p><?php echo $this->element('admin_nav'); ?></p>

    <?php echo $this->Form->create('Photo'); ?>
        <fieldset>
            <legend><?php echo __('Add Photo'); ?></legend>
        <?php
            echo $this->Form->input('account_id', array('type'=>'hidden'));
            //echo $this->Form->input('filename', array('type'=>'hidden'));
            echo $this->Form->input('filename', array('type' => 'file', 'label' => 'Upload photo'));
            echo $this->Form->input('desc');
            echo $this->Form->input('Tag' , array('label'=>'Tags', 'multiple'=>'checkbox'));

        ?>
        </fieldset>
    <?php echo $this->Form->end(__('Submit')); ?>
    </div>

While the Cakephp documentation on Saving Data makes references to how the array should be formatted, this appears to refer to all of the other relationships excluding HABTM. HABTM relationships can be saved in one action with the save on the parent model, in this case the Photo model eg:

   $this->Photo->save($this->request->data)

will save the new Photo being added, plus any of the selected Tags, and they will be saved in the join table photostags.

What is a bit unusual, is that $this->Photo->save($this->request->data) appears to work same as $this->Photo->saveAll($this->request->data).