CAKEPHP 3.x - 实体更新时出错 - 即使有值,也会声明缺少字段

Posted

技术标签:

【中文标题】CAKEPHP 3.x - 实体更新时出错 - 即使有值,也会声明缺少字段【英文标题】:CAKEPHP 3.x - Error on entity update - missing fields claimed even when have values 【发布时间】:2016-03-27 12:42:12 【问题描述】:

我有一个实体(预订),我手动为其设置了一些值,而其他值是使用 patchEntity 设置的。 但是在保存时,我收到一条错误消息,指出缺少两个必填字段。

这是实体调试的样子:

object(App\Model\Entity\Booking) 

    'provider_pk' => (int) 2,
    'date' => object(Cake\I18n\Time) 

        'time' => '2016-03-31T00:00:00+00:00',
        'timezone' => 'UTC',
        'fixedNowTime' => false

    ,
    'start' => object(Cake\I18n\Time) 

        'time' => '2016-03-31T08:00:00+00:00',
        'timezone' => 'UTC',
        'fixedNowTime' => false

    ,
    'modules_count' => (int) 1,
    'requester_pk' => (int) 1,
    'remarks' => '',
    'status_id' => (int) 1,
    'end' => object(Cake\I18n\Time) 

        'time' => '2016-03-31T09:00:00+00:00',
        'timezone' => 'UTC',
        'fixedNowTime' => false

    ,
    '[new]' => true,
    '[accessible]' => [
        '*' => true
    ],
    '[dirty]' => [
        'provider_pk' => true,
        'date' => true,
        'start' => true,
        'modules_count' => true,
        'requester_pk' => true,
        'remarks' => true,
        'status_id' => true,
        'end' => true
    ],
    '[original]' => [],
    '[virtual]' => [],
    '[errors]' => [
        'date' => [
            '_required' => 'This field is required'
        ],
        'start' => [
            '_required' => 'This field is required'
        ]
    ],
    '[invalid]' => [],
    '[repository]' => 'Bookings'


如您所见,“日期”和“开始”字段有值,但在错误部分中,显示它们缺失。

这就是我创建新实体的方式($date 和 $start 具有相应的值):

    $booking = $this->Bookings->newEntity( [ 'provider_pk' => $provider_pk, 'date' => $date, 'start' => $start ] );

然后我使用patchEntity,在保存之前,我手动设置了另一个字段,然后尝试这样保存:

   $booking = $this->Bookings->patchEntity($booking, $this->request->data);

    $booking->end = $end->modify( '+' . $booking->modules_count .  ' hours' );
    if ($this->Bookings->save($booking)) 
    
        $this->Flash->success(__('The booking has been saved.'));
        return $this->redirect( ['action' => 'show' ] );
     else ...

然后 $booking->errors() 给出这个:

[

    'date' => [
        '_required' => 'This field is required'
    ],
    'start' => [
        '_required' => 'This field is required'
    ]
]

如您所见,即使最初有值,也声称需要日期和开始字段。

我做错了什么?

这是表格模型:

<?php
namespace App\Model\Table;

use App\Model\Entity\Booking;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;

/**
 * Bookings Model
 *
 * @property \Cake\ORM\Association\BelongsTo $Statuses
 */
class BookingsTable extends Table


    /**
     * Initialize method
     *
     * @param array $config The configuration for the Table.
     * @return void
     */
    public function initialize(array $config)
    
        parent::initialize($config);

        $this->table('bookings');
        $this->displayField('id');
        $this->primaryKey('id');

        $this->belongsTo('Statuses', [
            'foreignKey' => 'status_id',
            'joinType' => 'INNER'
        ]);

        // ---------------------------------------------------------------------
        // customize for every project

        $this->hasMany( 'Aircrafts' );
        $this->belongsTo( 'Pilots', [ 'foreignKey' => 'requester_pk', 'joinType' => 'LEFT' ] );

    

    /**
     * Default validation rules.
     *
     * @param \Cake\Validation\Validator $validator Validator instance.
     * @return \Cake\Validation\Validator
     */
    public function validationDefault(Validator $validator)
    
        $validator
            ->integer('id')
            ->allowEmpty('id', 'create');

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

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

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

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

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

        $validator
            ->integer('provider_pk')
            ->allowEmpty('provider_pk');

        $validator
            ->integer('assistant_pk')
            ->allowEmpty('assistant_pk');

        $validator
            ->allowEmpty('remarks');

        return $validator;
    

    /**
     * Returns a rules checker object that will be used for validating
     * application integrity.
     *
     * @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
     * @return \Cake\ORM\RulesChecker
     */
    public function buildRules(RulesChecker $rules)
    
        $rules->add($rules->existsIn(['status_id'], 'Statuses'));
        return $rules;
    

这是控制器方法:

/** form for booking confirmation
*
* @param string|null $id cell id.
* @return \Cake\Network\Response|null Redirects to bookings / show .
**/

public function confirmBooking()

    if( isset( $this->request->query['id']) )
    
        $id = $this->request->query['id'];

        $token = strpos( $id, '-' );

        $day = substr( $id, $token + 1 , 2 );
        $month = substr( $id, $token + 3 , 2 );
        $year = substr( $id, $token + 5 , 4 );
        $hour = substr( $id, $token + 9 , 2 );
        $minutes = substr( $id, $token + 11, 2 );

        $date = Time::createFromTimestamp( mktime( 0, 0, 0, $month, $day, $year ) );
        $start = Time::createFromTimestamp( mktime( $hour, $minutes, 0, $month, $day, $year ) );
        $end = Time::createFromTimestamp( mktime( $hour + 1, $minutes, 0, $month, $day, $year ) );
        $provider_pk = substr( $id, 1, $token - 1 );
    

    $aircrafts =  $this->Bookings->Aircrafts->find( 'all', [ 'order' => 'registration' ] );
    $this->set( 'aircrafts', $aircrafts );

    // ---------------------------------------------------------------------
    // depending on add or update

    if( isset( $this->request->query['booking_id'] ) )
        $booking = $this->Bookings->get($this->request->query['booking_id'], [ 'contain' => [ 'Pilots' ] ] );
    else
    
        $booking = $this->Bookings->newEntity( [ 'provider_pk' => $provider_pk, 'date' => $date, 'start' => $start, 'end' => $end, 'modules_count' => 1 ] );
    

    if ($this->request->is('post') || ( $this->request->is('put') &&  isset( $this->request->query['booking_id'] ) ) ) 

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

        $booking = $this->Bookings->patchEntity($booking, $this->request->data);

        $booking->end = $end->hour( $this->request->data[ 'end_value' ][ 'hour' ] );

        $booking->modules_count = $booking->end->diff( $booking->start )->format('%h');


        if ($this->Bookings->save($booking)) 
        
            $this->Flash->success(__('The booking has been saved.'));
            return $this->redirect( ['action' => 'show' ] );
         else 
        
            $this->Flash->error(__('The booking could not be saved. Please, try again.')  );
            return $this->redirect(['action' => 'show']);
        
    

    $statuses = $this->Bookings->Statuses->find('list', ['limit' => 200]);
    $assistants = $this->Bookings->Pilots->find( 'list' , [ 'conditions' => [ 'is_instructor =' => true ], 'fields' => [ 'id', 'firstname' ] ] );        
    $providers = $this->Bookings->Aircrafts->find( 'list' , [ 'fields' => [ 'id', 'registration' ] ] );        
    $requesters = $this->Bookings->Pilots->find( 'list' , [ 'fields' => [ 'id', 'lastname' ] ] );        

    $this->set(compact('booking', 'statuses'));

    $this->set('_serialize', ['booking']);
    $this->set( 'assistants', $assistants );
    $this->set( 'providers', $providers );
    $this->set( 'requesters', $requesters );
        

【问题讨论】:

您能否向我们展示所有表格代码以及您正在执行此操作的控制器操作?你只是给了我们一小块拼图。 【参考方案1】:

我想我找到了问题所在。 问题是验证器中的“requirePresence”规则。 由于该字段不是通过表单获取的(由控制器设置为默认值),因此它不存在于传递的数组中。 我说的对吗?

问候。 法昆多。

【讨论】:

以上是关于CAKEPHP 3.x - 实体更新时出错 - 即使有值,也会声明缺少字段的主要内容,如果未能解决你的问题,请参考以下文章

Cakephp 验证更新实体上的数据

CakePHP 3.x 视图 URL 的下拉菜单

cakephp3 如何检查实体是不是是新插入的 afterSave 回调?

尝试烘烤时出错。 #cakephp

CakePHP 3 编辑上传

Cakephp 3 先保存翻译。之后的原始实体