【问题标题】:CakePHP saving hasMany through custom formCakePHP 通过自定义表单保存 hasMany
【发布时间】:2014-03-06 21:57:10
【问题描述】:

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'
            )
        );
}

参数值模型:

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,但它没有返回任何数据,另一方面,它不会将任何内容保存到我的连接表中。用户和参数值始终保证存在。

任何意见将不胜感激,很高兴回答更多问题。

【问题讨论】:

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


    【解决方案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 的行为。诀窍是传入数组的索引部分,而不是完整的键控父数组。必须直接在连接模型上进行保存才能使其正常工作(尽管我会就如何改进我这样做的方式提出任何意见)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多