【问题标题】:CakePHP empty Fields of associations are saved instead of discardCakePHP empty 关联的字段被保存而不是丢弃
【发布时间】:2017-01-05 13:43:27
【问题描述】:

我有一个关于 CakePHP 的小项目。它有一个名为articles的表,以及category、tags、images等5个Fields表。关联大多是HasOne,关联表有多个列。 在文章表上保存数据时,一切看起来都不错,但在某些关联上,例如:文章 -> 评级,如果我没有填写评级表的某些字段,则将其保存为空:

+----+------------+--------------+
| id | article_id | rating_value |
+----+------------+--------------+
|  1 |         36 |            3 |
|  2 |         56 |      5454.56 |
|  3 |         57 |            4 |
|  5 |         51 |         NULL |
+----+------------+--------------+

如果我添加了一些验证,则我无法保存文章,因为它需要验证。我想要的是,如果 rating_value 为空,那么它不能被创建为 null(实体被拒绝),并且必须保存文章。 删除文章按预期工作,所有相关实体都被删除。

我尝试在 Model.beforeMarshall 上更改 $data,但该类在 Tables Articles 和 Ratings 中都是私有的(我认为关联可能是问题所在)。

一些代码(控制器添加):

public function add()
    {
    $article = $this->Articles->newEntity();
    if ($this->request->is('post')) {
                $article = $this->Articles->patchEntity($article, $this->request->data, [
                    'associated' => [
                        'Ratings',
                    ]
                ]);
                if ($this->Articles->save($article)) {
                    $this->Flash->success(__('Saved.'));
                    return $this->redirect(['action' => 'index']);
                }
    }
    $this->set('article', $article);
}

因此,我删除了每个关联模型的所有验证。

// Articles Table
$this->hasOne('Ratings', [
    'className' => 'Ratings',
    'dependent' => true,
]);

// Ratings Table
$this->belongsTo('Articles', [
    'foreignKey' => 'article_id',
    'joinType' => 'INNER'
]);
// Rating.php Entity
protected $_accessible = [
    '*' => true,
    'id' => false
];
// Article.php Entity
protected $_accessible = [
    '*' => true,
];

【问题讨论】:

  • "我尝试在 Model.beforeMarshall 上更改 $data"... 显示您尝试过的内容,因为这是要走的路(至少一种方式)。还要详细说明“类是私有的”,这句话对我来说真的没有意义。
  • 在 Articles.beforeMarshall var_dump($data) 上显示 object(ArrayObject)[272] private 'storage' => ... 我无法修改数据,而 Ratings.beforeMarshall 相同 object(ArrayObject)[231] private 'storage' => ...
  • 这就是转储array object 的样子,它的内部是私有的,但是可以不受限制地访问数据,只需像编辑任何其他数组一样编辑$databook.cakephp.org/3.0/en/orm/…
  • 你一直都是对的。我试图编辑 $data->storage... 或 $data['storage']... 之类的数据,但只有 $data['field'] 有效。我认为这是一个比在控制器上做更好的解决方案。

标签: php cakephp cakephp-3.3


【解决方案1】:

如果您正在设置 rating_value,那么它将尝试保存并使用所有验证规则进行验证。

如果 rating_value 像这样为空,您可以删除关联数据

$dataToSave = $this->request->data;
if(empty($dataToSave['rating']['rating_value'])){
    unset($dataToSave['rating']);
}
$article = $this->Articles->patchEntity($article, $dataToSave, [
    'associated' => [
        'Ratings',
    ]
]);

【讨论】:

  • 它似乎可以工作,但控制器是最好的地方吗?我的意思是我将添加一些 foreach 项目以查看一个是否为空,并在添加/编辑动作时对每个项目进行审查。
【解决方案2】:

我觉得每件事看起来都不错。可能是表中的字段默认值为 null。例如:

If 'rating_value' field in your table has default value null,
make that default full to none first.

如果验证失败并没有让您保存任何内容而不是保存空值。如果这仍然对您不起作用:

debug($this->request->data);

如果数据从您的视图(表单)中正确显示,请查看那里。 另一个重要的事情是您可以使用不同的验证集进行关联。 (see here)

【讨论】:

  • 如果默认不为空则:Error: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'rating_value' cannot be null
  • 你定义了在 mysql 中插入数据的触发器吗?否则你的 rating_value 仍然为 null..你需要查看 debug($this->request-.data)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-24
相关资源
最近更新 更多