Связь «Один к одному» (One to one)

Связь «Один к одному» (One to one) позволяет реализовать такой функционал, как автор статьи.

В таблице, например «posts», надо создать поле user_id (тип «INT»), и в модели добавить метод $this->belongsTo(), внутри которого указать таблицу с пользователями.

# src/Model/Table/PostsTable.php

class PostsTable extends Table
{
    public function initialize(array $config): void
    {
        // …
        $this->belongsTo('Users');
    }
}

Теперь когда надо выбрать статью вместе с данными пользователя, надо добавить параметр contain.

// 1-ый способ
$posts = $this->Posts->find('all', [
    'contain' => 'Users'
]);

// 2-ой способ
$posts = $this->Posts->find('all')->contain('Users');

// пример вывода имени пользователя
foreach ($posts as $post) {
    $post->user->name;
}

Форма для выборки пользователя

CakePHP автоматически определит, что для поля «user_id» надо выводить выпадающий список. Добавить пользователей в выпадающий список можно через свойство options.

# контроллер
$users = $this->Posts->Users->find('list', [
    'keyField' => 'id',
    'valueField' => 'name'
]);

$this->set(compact('users'));

# шаблон
echo $this->Form->control('user_id', ['options' => $users]);

Код выше также выбирает текущего пользователя в выпадающем списке как значение по умолчанию.

Не сохранять запись, если указан несуществующий пользователь

Выводить ошибку, если указан не существующий пользователь, можно, указав в модели src/Model/Table/PostsTable.php правило $rules->existsIn().

# src/Model/Table/PostsTable.php

class PostsTable extends Table
{
    public function buildRules(RulesChecker $rules): RulesChecker
    {
        // проверять, что указанный пользователь существует
        $rules->add($rules->existsIn(['user_id'], 'Users'));

        return $rules;
    }
}