【问题标题】:Editing associated models data in cakephp在 cakephp 中编辑关联模型数据
【发布时间】:2014-05-15 07:08:57
【问题描述】:

我使用的是 CakePHP 2.3.6。我的项目中有一些模型,它们是关联的,并且我明确定义了关联。现在,我有一个编辑表单,在其中检索所有模型数据,并尝试在相应模型中编辑这些数据。但是,没有发生编辑,而是在关联的表中创建了新行。

这是我在模型之间的关联:

在模型User.php

public $hasMany=array('Education'=>array(
                            'className'=>'Education
                            'foreignKey'=>'user_id'
                      ),
                      'Experience'=>array(
                            'className'=>'Experience',
                            'foreignKey'=>'user_id'
                      ),
                      'Employment'=>array(
                            'className'=>'Employment',
                            'foreignKey'=>'user_id'
                      ),
                      'ProfessionalQualification'=>array(
                            'className'=>'ProfessionalQualification',
                            'foreignKey'=>'user_id'
                      )
)

在模型Education.php

public $belongsTo=array('User'=>array(
                            'className'=>'User',
                            'foreignKey'=>'user_id'
                        )
)

在模型Experience.php

public $belongsTo=array('User'=>array(
                            'className'=>'User',
                            'foreignKey'=>'user_id'
                        )
)

在模型Employment.php

public $belongsTo=array('User'=>array(
                            'className'=>'User',
                            'foreignKey'=>'user_id'
                        )
)

在模型ProfessionalQualification.php

public $belongsTo=array('User'=>array(
                            'className'=>'User',
                            'foreignKey'=>'user_id'
                        )
)

现在,在编辑表单中 (View/Users/edit.ctp):

echo $this->Form->create('User');
echo $this->Form->input('User.name');
echo $this->Form->input('User.username');
echo $this->Form->input('User.password');
echo $this->Form->input('User.address');
echo $this->Form->input('User.phone');
echo $this->Form->input('Education.0.degree');
echo $this->Form->input('Education.0.passing_year');
echo $this->Form->input('Experience.0.title');
echo $this->Form->input('Experience.0.description');
echo $this->Form->input('Employment.0.company');
echo $this->Form->input('Employment.0.description');
echo $this->Form->input('ProfessionalQualification.0.certificate');
echo $this->Form->input('ProfessionalQualification.0.description');
echo $this->Form->submit('Save');
echo $this->Form->end();

UsersController.php 控制器中:

public function edit(){
  $this->set('title_for_layout','Edit CV');
  if(!AuthComponent::user('id'))
     throw new NotFoundException(__('Invalid User'));
  $user=$this->User->findById(AuthComponent::user('id'));
  if(!$user)
     throw new NotFoundException(__('Invalid User'));
  if($this->request->is('post') || $this->request->is('put')){
     if(!$this->User->saveAll($this->request->data)){
        $this->Session->setFlash('Sorry, your info could not be saved. Please, try again.');
        $this->redirect(array('action'=>'edit'));
     }
  }
  if(!$this->request->data)
     $this->request->data=$user;
}

在这里,我正在 User 模型上尝试 saveAll() 功能。我还尝试使用save()saveAssociated() 函数,但结果相同。它不会改变表中的对应行,而是在所有表中创建一个新行,接受users表,该表成功获取新值并更新值。

我该怎么办?请帮帮我。

谢谢

【问题讨论】:

  • 你试过用updateAll代替saveAll吗?
  • 我应该如何使用它,像这样: $this->User->updateAll($this->request->data) ?它也不起作用,相反,它给出了一个错误:数组到字符串转换
  • 在调用$this->User->saveAll($this->request->data)之前使用用户ID初始化$this->User->id
  • 是的,我做到了,但结果相同。谢谢@Console

标签: cakephp model-associations updatemodel


【解决方案1】:

这是一种使它起作用的方法(理论上),但我不确定它是最好的,而且它不是“安全的”:在表单中添加相关字段的 ID,并带有隐藏字段,如下所示:

echo $this->Form->create('User');
echo $this->Form->hidden('User.id');
echo $this->Form->input('User.name');
/* ... */
echo $this->Form->hidden('Education.0.id');
echo $this->Form->input('Education.0.degree');
/* ... */
echo $this->Form->hidden('Employment.0.id');
echo $this->Form->input('Employment.0.company');
/* ... */
echo $this->Form->submit('Save');
echo $this->Form->end();

您应该在控制器中检查关联模型的 id 是否与主模型的 id 匹配,否则人们将能够编辑未与其用户模型链接的关联模型。

编辑:这是对评论中讨论的进一步解释的编辑。

当你有hasMany 关系时,像这样:

public $hasMany = array('Experience') ; // In User class

您必须在保存关系时指定 ID,否则 Cake 引擎无法推断您要更新模型而不是保存模型。

$data = array(
    'User' => array(
        'id' => 33,
        'name' => 'Holt'
    ),
    'Experience' => array(
        array(
            /* 'id' => 45, */
            'name' => 'PHP'
        )
    )
) ;
$this->User->saveAssociated($data) ;

在这里,您知道您所指的UserHolt,ID 为33,因此您知道以下数组中的体验指的是该用户。但是,如果您没有在 Experience 数组中指定 id 字段,引擎如何知道您指的是哪种体验

如果关系是belongsTo,很容易推断这是与用户Holt 相关的Experience(根据关系belongsTohasOne,每个用户只有一个Experience),并且顺便说一句,你不会有嵌套数组。

有多种方法可以告诉引擎您要更新模型,我使用的两种方法是:

  • data 数组中设置id 值(如上)
  • 在控制器中设置 $this->Model->id 值:当您执行 $this->Model->read$this->Model->find 时,会隐式设置此值(就像您一样)

我可以肯定的是,第一个选项适用于关联模型(如上面的 data 数组,如果您取消注释 id),我不确定第二个是否有效关联模型,比如$this->User->Experience->id = ...,你可以试试,我现在查不到。

【讨论】:

  • 是的,我知道这个技巧,但我不喜欢它。如果我必须像这样更新关联值,那我为什么要使用关联?我可以简单地单独保存(更新)所有表。顺便说一句,谢谢你的帮助。 @霍尔特
  • @SubhasishSaha 是的,我知道这很棘手。我没有看到您在代码中检索帖子数据的位置,您能检查一下吗?
  • @SubhasishSaha 我说的是你的帖子,你保存的是$user 变量而不是$this->data
  • @Isengo 因为它允许用户更改 id 值(即使该字段被隐藏,也很容易这样做),因此他们可以更新或窃取不属于他们的条目.
  • @Isengo 在您的控制器中,您可以检查您保存的条目是否尚不存在(您将要创建它们)或已属于关联模型。可能有更简单的方法,我不知道思想。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多