CakePHP保存有很多通过自定义表单

时间:2014-02-09 17:35:40

标签: php cakephp model relationship has-many-through

对CakePHP来说很新,并试图通过一个复杂的(至少在我看来,欢迎简化)关联并遇到一些困难。请耐心等待,因为它似乎有很多信息。

差不多,我有一个动态的参数列表和相关的动态值,所以我通过获取参数的所有hasMany ParameterValues在我的视图中构建了一个无模型的表单。

控制器:

$this->loadModel('Parameter');
$this->set('parameters', $this->Parameter->find('all'));

查看:

            echo $this->Form->create(false, array(
                                        'inputDefaults' => array(
                                            'div' => 'form-group',
                                            'wrapInput' => false,
                                            'class' => 'form-control'
                                        ),
                                        'class' => 'well form-horizontal',
                                        'url' => '/dashboard'
                                    ));

            foreach($parameters as $parameter) 
            {
                $options = array();
                $selected = array();
                foreach($parameter['ParameterValue'] as $parameter_value)
                {
                    if(strtolower($parameter_value['default']) == false || $parameter['Parameter']['is_multivalue'])
                    {
                        $options[$parameter_value['id']] = $parameter_value['value'];
                    }
                }

                echo $this->Form->input($parameter['Parameter']['name'], array(
                    'label' => __($parameter['Parameter']['name']),
                    'type'=>'select',
                    'options'=>$options,
                    'required'=>true,
                    'multiple'=>$parameter['Parameter']['is_multivalue'],
                    'error' => array('isValid' => 'Must enter a birthday.'),
                    'after' => ($parameter['Parameter']['is_multivalue'] ? '<span class="help-block">Select one or more options.</span>' : ''),
                    'empty'=> ($parameter['Parameter']['is_multivalue'] ? '' : 'Pick An Option')));
            }

            echo $this->Form->submit('Submit', array(
                                            'div' => 'form-group',
                                            'class' => 'btn btn-default'
                                        ));
            echo $this->Form->end();

这很好用,我可以手动设置后端的连接,看看这里显示的是选中的值。我遇到的问题是选择全部值,然后将它们保存到数据库中。

用户模型:

App::uses('User', 'Users.Model');
class CustomUser extends User 
{
    public $name = 'CustomUser';

    public $useTable = 'users';

    public $hasMany = array(
            'ParameterValueUser'
        );  
}

ParameterValueUser型号:

App::uses('AppModel', 'Model');
class ParameterValueUser extends AppModel 
{
    public $name = 'ParameterValueUser';

    public $useTable = 'parameter_values_users';

    public $belongsTo = array(
            'CustomUser'=>array(
                'className'    => 'CustomUser',
                'foreignKey'   => 'user_id'
            ),
           'ParameterValue' => array(
                'className'    => 'ParameterValue',
                'foreignKey'   => 'parameter_value_id'
            )
        );
}

ParameterValue模型:

class ParameterValue extends AppModel 
{
    public $name = 'ParameterValue';

    public $actsAs = array('Containable');

    public $belongsTo = array(
        'Parameter'=>array(
            'className' => 'Parameter',
            'foreignKey' => 'parameter_id')
        );

    public $hasMany = array('ParameterValueUser');
}

然后我通过重建所需的数组来保存数据:

CustomUserController操作信息中心:

    if (!empty($this->request->data)) 
    {
        $data = array();

        $data['CustomUser']['id'] = $this->Auth->user('id');

        foreach($this->request->data as $key => $values)
        {
            if(is_array($values))
            {
                foreach($values as $value)
                {
                    $data['ParameterValueUsers'][] = array('parameter_value_id'=>$value);
                }
            } else {
                $data['ParameterValueUsers'][] = array('parameter_value_id'=>$values);
            }
        }

        $this->CustomUser->saveAll($data, array('deep' => true));
        $this->set('result', $data);
    }

这为8个参数提供了类似的输出

Array
(
[CustomUser] => Array
    (
        [id] => 52f44de4-ccb0-4a87-9861-1830c6fc40a8
    )

[ParameterValueUsers] => Array
    (
        [0] => Array
            (
                [parameter_value_id] => 1
            )

        [1] => Array
            (
                [parameter_value_id] => 5
            )

        ...

        [7] => Array
            (
                [parameter_value_id] => 209
            )

    )

)

目标是使用将每个用户链接到参数的表单值覆盖那里的所有链接。我试过HABTM,但它没有返回任何数据,另一方面,这不会保存到我的连接表中。始终保证用户和参数值存在。

任何意见都会受到赞赏,很高兴回答更多问题。

1 个答案:

答案 0 :(得分:1)

玩了一会儿后,我发现我的方式的错误几乎就是我传递给saveAll的错误。很多例子都显示了带有索引子数组的键控数组,用于保存许多关系,这使我误入歧途(或者我用错了)

最终代码如下所示:

    if (!empty($this->request->data)) 
    {
        $data = array();

        foreach($this->request->data as $key => $values)
        {
            if(is_array($values))
            {
                foreach($values as $value)
                {
                    $data['ParameterValueUsers'][] = array('parameter_value_id'=>$value,'user_id'=>$this->Auth->user('id'));
                }
            } else {
                $data['ParameterValueUsers'][] = array('parameter_value_id'=>$values,'user_id'=>$this->Auth->user('id'));
            }
        }
        $this->CustomUser->ParameterValueUser->deleteAll(array('user_id' => $this->Auth->user('id')));
        $this->loadModel('ParameterValueUser');
        $this->ParameterValueUser->saveAll($data['ParameterValueUsers']);
    }

我通过首先删除所有旧关联来强制执行类似HABTM的行为。诀窍是传入数组的索引部分,而不是完整的键控父数组。保存必须直接在连接模型上完成才能使它工作(尽管我会对如何改进我的方式进行任何输入)。