I use CakeDC plugin. I want to link another player_heroes table to the users table. added field to profile edit

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

added controller to 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));} 

in Entity\Users.php registered hasMany ( uid field in the player_heroes table)

  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']); } 

After saving the profile, the users table is updated, and player_heroes empty. Maybe it's in the ways? Users is in vendor/cakedc/src/ , and PlayerHeroes at the root of app/src/ . No mistakes knocks out

  • If you want to make multiple choices, then you need a belongsToMany connection and an intermediate table to store it. If this connection is itself represented as an entity, then for this there is a through option in the config. - teran
  • and in the field name, you may need to specify the full path to select("Users.PlayersHeroes.hero") , although for selects it is usually written ._ids if you have checkboxes for your choice. In general, it’s not quite clear to me what and how you want to link and edit at all - teran
  • associated patch prescribed when they want to change the data themselves. if you only need to keep the connection, it is not necessary. So make it clear what you are trying to do at all - teran
  • there is a table users, I want to add lines to the player_heroes table - one player can have several heroes, i.e. users hasMany player_heroes. when a player rules a profile, I want to add / remove rows from the player_heroes table from keel - on
  • one hell is not clear. Option 1) You already have a list of heroes with whom you want to set up links, so you have multiple select boxes. In this case, you need the belongsToMany link and select for _ids . Option 2) you want to directly create characters for the user. But then you need not selects with checkboxes, but input for entering the names of heroes, and then, yes, you need the associated patchEntity . I think you need option 1 - with many to many connections. Each user can select several heroes of the common list, and a hero can be selected by several users. - teran

1 answer 1

summarize the discussion in the comments.

We have: the Users table and the Heroes table, and we want to link them, so that when editing a user, we can select several heroes values.

This relationship is described by a многие-ко-многим relationship, and is implemented using belongsToMany . According to cakephp naming conventions , the link table must be called using the names of the linked tables in alphabetical order, and have keys in the singular names of the tables with the suffix _id .

Thus, to implement the connection, you need a table heroes_users with the fields id, user_id, hero_id .

You have the connection table ( players_heroes ) already created, and has the structure id, uid, heroid . What makes us manually configure the connection.

In addition, when using names that do not comply with the accepted naming rules, it makes it impossible for you to normally generate table and model classes using the cake bake model .

As a result, you need to configure the Users table as follows:

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

and now in the editing template it remains to display

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

where $heroes is the list obtained by

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

The above code is enough to save many-to-many connections.


In addition, there are two more things in the code you give.

  1. PlayerHeroes entity. It is not needed to simply keep the link. The need for this arises when, in addition to the fact of choice, you need to store and add. information. For example, besides the choice, it is also important to remember the order, or to mark some hero as favorites . Then the players_heroes table players_heroes supplemented with new columns, a separate entity is created for this table, and the configuration adds a through option indicating the class of this link table.

  2. associated in patchEntity . Again, this is not necessary for simple communication. This parameter can be used when we, for example, simultaneously with the preservation of the connection, decide also to rename the hero.