CakePHP 3.x - 保存这些表的关联数据和表单输入

Posted

技术标签:

【中文标题】CakePHP 3.x - 保存这些表的关联数据和表单输入【英文标题】:CakePHP 3.x - Saving associated data and form inputs of those tables 【发布时间】:2017-02-01 11:18:56 【问题描述】:

我有 3 张桌子:

预订 付款 会话

在我的作为 Bookings 表一部分的表单中,虽然我有几个 Payments 独有的属性(例如 Amount、Depositpaid、Status),但只有一个具有表单输入 - 其他所有内容都与 Sessions 相关:

echo $this->Form->hidden('payments.amount',['type'=>'number', 'value'=>'0', 'step'=>'0.01', 'class'=>'currency form-control']);

在 BookingsController 中,我有以下内容:

$booking = $this->Bookings->newEntity([
            'associated' => ['Payments', 'Sessions']
            ]]);
        if ($this->request->is('post')) 
            $data = $this->request->data;
            $booking = $this->Bookings->patchEntity($booking, $data, [
                'associated' => ['Payments', 'Sessions']
            ]);
...

$save = $this->Bookings->save($booking);

...

点击表单上的提交后,Bookings 和 Sessions 中的数据都会被保存。在 post 数据中,有两个数组:Session 数组和 Payments 数组。在 Booking 数组中的变量数据中,有一个 Associated 数组,其中包含两个元素:0 Payments,1 Sessions。

但是,在 SQL 日志中,没有 Insert Into for Payments 表。在对 $booking(patchEntity 之一)进行调试时,Payments 是一个空数组,如下所示:

'payments' => [],

我还对 patchEntity 之后的 $save 进行了调试,并为“付款”获得了相同的结果。

当涉及到非空值和验证时,我检查了我的 Payments 表模型和 mysql 中的相应结构。

下面是关于验证的支付模型(PaymentsTable):

public function validationDefault(Validator $validator)
    
        $validator
            ->integer('id')
            ->allowEmpty('id', 'create');

        $validator
            ->allowEmpty('paymentmethod','create');

        $validator
            ->decimal('amount')
            ->requirePresence('amount', 'create')
            ->notEmpty('amount');

        $validator
            ->requirePresence('status', 'create')
            ->notEmpty('status');

        $validator
            ->integer('depositpaid')
            ->allowEmpty('depositpaid', 'create');

        $validator
            ->allowEmpty('uniqid', 'create');

        return $validator;
    

在我的 MySQL 数据库中,我将属性“status”设置为在创建新数据条目时自动设置为“notpaid”,并将属性“amount”设置为默认值“0.00”。唯一不为空的字段是“id”、“booking_id”(链接到 Booking 表 id 的外键)、“金额”和“状态”。

所以我想我的问题是:我没有保存此关联表的原因是因为我没有为其余的 Payments 属性输入表单输入(隐藏或其他方式),还是我遗漏了什么?

更新:

好的,我在表单输入(payments.0.amount)中添加了一个0,这次提交没有成功。在再次调试 patchEntity - 'debug($booking)' 时,我在支付数组中发现了这个错误:

'[errors]' => [
                'status' => [
                    '_required' => 'This field is required'
                ]

即使我声明将状态设置为自动放入默认字符串也是如此。我是否需要在控制器中执行类似 $this->request->data['status'] 的操作?如果是这样,它与非关联数据的属性有何不同(例如,$this->request->data['attribute'] 用于非关联数据)?

我已经试过了:

$this->request->data['status'] = 'notpaid';
$this->request->data['payments']['status'] = 'notpaid';
$this->request->data['payments'][0]['status'] = 'notpaid';
$this->request->data['payments']['0']['status'] = 'notpaid';

所有都没有成功,并且在 patchEntity 调试中收到相同的错误。有效的方法是在另一个表单输入中添加“状态”(表示它是必需的属性),但是虽然我已经解决了我的问题,但我仍然想知道如何从控制器输入相关数据。

【问题讨论】:

假设预订hasMany 付款,可能就像将输入字段从payments.amount 更改为payments.0.amount 一样简单。 好吧我加了一个0,这次提交没有成功。调试时发现错误,如更新后的帖子所示。 最终采用了迂回的方法,只是为状态添加了另一个隐藏的表单输入。虽然我仍然对如何从控制器正确输入相关数据感到好奇……还没有弄清楚。 根据您尝试获取其中状态的所有不同方式,您似乎不太了解请求数据的格式。你试过debug($this->request->data) 看看它已经是什么样子了吗?那应该指出如何添加状态的方法。此外,如果您在创建记录时实际上不需要显示状态,则可以删除验证中的 ->requirePresence('status', 'create') 部分。 【参考方案1】:

我通过添加另一个隐藏的表单输入来修复它,尽管我仍然想知道如何通过控制器而不是视图输入关联数据。

【讨论】:

以上是关于CakePHP 3.x - 保存这些表的关联数据和表单输入的主要内容,如果未能解决你的问题,请参考以下文章

如何将数据写入 CakePHP 中 HABTM 连接表的 HABTM 关联?

在 CakePHP 中保存新的关联记录

CakePHP 3.x 从实体获取相关数据

CakePHP patchEntity 不保存数据(“通过”关联)

在 CakePHP 3 中保存 belongsToMany 关联

CakePHP 2.1 - 模型关联 - 保存和查找