Связи associated в Cake PHP 3.6

138
27 апреля 2018, 12:46

использую плагин CakeDC. хочу к таблице users привязать другую таблицу player_heroes. в редактирование профиля добавил поле

$this->Form->select('PlayerHeroes.hero', $heroes, 
            ['multiple' => true,
             'id'=>'fav-hero-select'
             ]);

в action контроллера добавил

$entity = $table->patchEntity($entity, $this->request->getData(), ['associated'=>['PlayerHeroes']]);
if ($table->save($entity)) {
            $this->Flash->success(__d('CakeDC/Users', 'The {0} has been saved', $singular));}

в Entity\Users.php прописал hasMany (uid поле в таблице player_heroes)

 public function initialize(array $config)
    {
        parent::initialize($config);
        $this->setTable('users');
        $this->setDisplayField('username');
        $this->setPrimaryKey('id');
        $this->addBehavior('Timestamp');
        $this->addBehavior('CakeDC/Users.Register');
        $this->addBehavior('CakeDC/Users.Password');
        $this->addBehavior('CakeDC/Users.AuthFinder');            
        $this->hasMany('PlayerHeroes', [
            'foreignKey' => 'uid']);
    }

После сохранения профиля таблица users обновляется, а player_heroes пуста. Может дело в путях? Users находится в vendor/cakedc/src/, а PlayerHeroes в корне app/src/. Никаких ошибок не выбивает

Answer 1

подытожу дискуссию в комментариях.

У нас имеется: таблицы Users и таблица Heroes и мы хотим связать их, так что бы при редактировании пользователя мы могли выбрать несколько значений heroes.

Данная связь описывается отношением многие-ко-многим, и реализуется с помощью belongsToMany. Согласно соглашениям об именовании в cakephp, таблица связи должна назыаться, используя имена связуемых таблицы в алфавитном порядке, и иметь ключи по названиям таблиц в единственном числе с суффиксом _id.

Таким образом, для реализации связи нужна таблица heroes_users с полями id, user_id, hero_id.

У вас же таблица связи (players_heroes) уже создана, и имеет структуру id, uid, heroid. Что заставляет нас вручную конфигурировать связь.

Помимо этого при использовании имен, не соответствующих принятым правилам именования, лишает вас возможности нормально генерировать классы таблицы и моделей с помощью cake bake model.

В итоге, требуется настроить таблицу Users следующим образом:

$this->belongsToMany('Heroes', [ 
              'joinTable' => 'players_heroes',
              'foreignKey' => 'uid',
              'targetForeignKey' => 'heroid'
         ]);

и теперь в шаблоне редактирования осталось вывести

$this->Form->select("heroes._ids", $heroes, ['multiple' => true]);

где $heroes это список полученный с помощью

 $ht = TableRegistry::get('default');
 $heroes = $ht->find('list')->toArray();

Приведенного кода достаточно для сохранения связей многие-ко-многим.

В дополнение, в приведенном вами коде фигурирует еще две вещи.

  1. сущность PlayerHeroes. Для простого сохранения связи она не нужна. Необходимость в таком возникает, когда помимо самого факта выбора нужно хранить и доп. информацию. Например, кроме выбора важен еще и запомнить порядок, либо какого то героя пометить как favorites. Тогда таблица players_heroes дополняется новыми столбцами, создается отдельная сущность для этой таблицы, и при конфигурации добавляется опция through, указывающая а класс этой связующей таблицы.

  2. associated в patchEntity. Опять же, для простого сохранения связи это не нужно. Этот параметр может использоваться когда мы, например, одновременно с сохранением связи, решим еще и переименовать героя.

READ ALSO
Нет изменений при вызове процедуры в WP

Нет изменений при вызове процедуры в WP

Есть такая часть кода, которая не работает

104
Запуск старого проекта

Запуск старого проекта

В руки попал очень старый проект, судя по синтаксису - примерно из 2013Нормально пытаюсь запустить на PHP 5

127
Работа с формами номер телефона

Работа с формами номер телефона

Как сделать что бы при нажатии на форма появлялось +7()___ и данные вписывались внутрь?

138
Jquery как обнулить цены

Jquery как обнулить цены

В приницпе всё готово, вот только я незнаю как обнулить цены (ибо они все разные) и снять чекбоксы, спасите люди добрыеfresh-diet

203