Как проверить обязательную связанную модель в cakephp 3

Я запутался в правильном (или лучшем) способе убедиться, что связанные модели отправляются через POST при создании нового пользователя. Оба подхода, перечисленные ниже, работают.

User hasOne UserDetails

Вариант 1

Почтовые данные:

{
    "username": "loremipsum",
    "password": "123456",
    "UserDetails": {
        "first_name": "Lorem",
        "last_name": "Ipsum"
    }
}

PatchEntity UserDetail и добавьте его в User Entity следующим образом:

public function add () {

    $user = $this->Users->newEntity();

    if ($this->request->is('post')) {
        $user = $this->Users->patchEntity($user, $this->request->data(), [
            'associated' => [], 
            'validate' => true
        ]);
        $userDetail = $this->Users->UserDetails->newEntity($this->request->data());
        $user->user_detail = $userDetail;

    if ($this->Users->save($user, ['associated' =>['UserDetails']]))
    { 
...

Редактировать 1: если UserDetails отсутствует в $this->request->data(), объект UserDetails получит ошибки проверки.

Вариант 2

Почтовые данные:

{
    "username": "loremipsum",
    "password": "123456",
    "user_detail": {
        "first_name": "Lorem",
        "last_name": "Ipsum"
    }
}

Добавьте проверку user_detail в UserTable.php:

Редактировать 2: если я не добавлю проверку user_detail, запрос можно будет отправить без связанной модели, и он будет сохранен. Его добавление гарантирует, что в $this->request->data() есть поле user_detail, а объект Users получит проверку.

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

и patchEntity, как это на UsersController.php:

public function add () {

    $user = $this->Users->newEntity();

    if ($this->request->is('post')) {
        $user = $this->Users->patchEntity($user, $this->request->data(), [
            'associated' => ['UserDetails'], 
            'validate' => true
        ]);

    if ($this->Users->save($user, ['associated' =>['UserDetails']]))
    { 
...

Соответствуют ли эти подходы соглашениям Cake или есть лучший/чистый способ сделать это?


person Bruno Serra    schedule 07.02.2017    source источник
comment
Вариант 2 - лучший вариант. И это даст вам ошибки проверки как для Users, так и для связанной модели UserDetails.   -  person Object Manipulator    schedule 07.02.2017
comment
@ObjectManipulator спасибо за ответ! На самом деле в обоих случаях проверка работает, потому что проверка выполняется при создании объекта. Основное отличие здесь в способе написания кода и отправки данных :)   -  person Bruno Serra    schedule 07.02.2017
comment
вариант 1 правильный .. вариант 2 не работает, это проверка только модели пользователей, а не сведений о пользователе .. спасибо, человек, ты действительно помог   -  person Soubhagya Kumar Barik    schedule 04.07.2018


Ответы (2)


Второй вариант является правильным вариантом по нескольким причинам IMO.

  1. Валидация должна быть на модели, к которой она относится.
  2. Валидация должна быть выразительной и явной. Если бы я был другим парнем, читающим этот код, я мог бы сказать, что для сохранения пользователя требуется проверка.
  3. Он более четкий и менее подвержен ошибкам.
  4. Совпадает с конвенцией о тортах. Я не видел ни в одном из их примеров, где вы бы сохранили одно, а затем спасли бы другое. Сохранение ассоциаций
person styks    schedule 09.02.2017
comment
Я отредактировал свой вопрос, чтобы было понятно. В обоих случаях данные сохраняются сразу; первый просто добавляет объект UserDetails отдельно. Дело в следующем: чтобы заставить UserDetails присутствовать в запросе, я должен использовать первый или второй вариант, который я дал? Спасибо! - person Bruno Serra; 09.02.2017

если вы хотите проверить несколько моделей, вам нужно создать несколько newEntity в соответствии с таблицей. Вот рабочий пример для ассоциации hasOne.

 public function add() {
        $user = $this->Users->newEntity();
        if ($this->request->is('post')) {
            $user = $this->Users->patchEntity($user, $this->request->getData());
            $userDetail = $this->UserDetails->newEntity($this->request->getData()['user_detail']);
            $user->user_detail = $userDetail;
            if ($this->Users->save($user)) {
                $this->Flash->success(__('The user has been saved.'));
                return $this->redirect($this->referer());
            } else {
                $this->Flash->error(__('The user could not be saved. Please, try again.'));
            }
        }
        $this->set(compact('user'));
    }
person Soubhagya Kumar Barik    schedule 04.07.2018