Insert with related rable


#1

Hii there,

So, I’m trying to create my new website and I got the beginning part of the registration to work.
I looked into the cookbook, but I couldn’t bake my cake with it :\

So, I want to insert something with the registration into the users_roles table (UsersRoles Class).
They are linked with a 1:n relationship.

all I want to insert is the id of the current user being inserted and the id of the default role (which has the value of 1).

This is my current code:

public function register(){
  $register = new RegisterForm();
  if ($this->request->is('post')) {
    $user = $this->Users->newEntity();
    $user = $this->Users->patchEntity($user, $this->request->getData());
    if ($this->Users->save($user)) {
      $this->Flash->success(__('The user has been saved.'));
      return $this->redirect(['controller' => 'Pages', 'action' => 'display', 'home']);
    }
    $this->Flash->error(__('Unable to add the user.'));
  }
  $this->set('register', $register);
}

I hope somebody will be able to help me out :slight_smile:
cheers!


#2

Since you want to add the new user’s ID into users_roles, you need to wait until the user is created. Then the ID is known.

In your UsersTable class, add the method afterSave.

public function afterSave(Event $event, EntityInterface $entity, \ArrayObject $options) 
{
    if($entity->isNew()) {

		$usersRole = $this->UsersRoles->newEntity();
		$usersRole->user_id = $entity->id;
		$usersRole->role_id = 1; // I'd recommend storing the default role_id value as a constant instead of hard coding it everywhere.
		$this->UsersRole->save($usersRole);
	}
}

I have not tested this. If this doesn’t work, if you’d be able to export the tables and dump it here, I can test further.

Edit:

This code might also insert a row into UsersRoles every time you edit that user. I added a check to represent this. Now the UsersRole will only be added if the entity (user) is new.


#3

Thanks for your response.
As far as I could tell, it seems to work fine :slight_smile:

EDIT: one small question, let’s say I want the $usersRole->role_id to be something else (let’s say 2) for 1 specific insert. How would I go about that?

EDIT2: I seem to be getting an error while trying to add a user with this: Table "App\Model\Table\UsersTable" is not associated with "UsersRoles".
I did rebuild my models using cake bake models all.
You can find my Table/UsersTable.php here (I put it on hastebin because it just seems a bit cleaner to do it like that for bigger pieces of code)

EDIT3: Solved the issue (EDIT2) above by using $this->Roles instead of $this->UserRoles.
I’m now getting Cannot commit transaction - rollback() has been already called in the nested transaction.

EDIT4: fixed both the issued in EDIT2 and EDIT3 :slight_smile:
Apparently, on line 50 of my UsersTable.php is said: $this->belongsToMany('Roles', [ which had to be $this->belongsToMany('UsersRoles', [.
So that only leaved the question in the first edit :slight_smile:


#4

In what case would you like to insert 2 instead of 1? I would either supply a select menu to the form containing roles to set as default added, or create an if statement if it should be out of the users control.

$usersRole->role_id = 1;
if(/* case when role 2 is to be inserted */)  {
    $usersRole->role_id = 2;
}

It really depends on when and why that use case is necessary.


#5

is there a reason why you are not saving it using association? https://book.cakephp.org/3.0/en/orm/saving-data.html#saving-belongstomany-associations


#6

If a user registers by themselves, it should by role_id=1.
But let’s say if I create an account for somebody through dashboard and I want to give him another role (for example role_id=2 or role_id=3, then I want to be able to do that.

The reason I didn’t save it using an association is because I don’t really understand how I would implement that…


#7

saving association isnt that hard once you have tried it once or twice, you just need to supply correct data structure format:

https://book.cakephp.org/3.0/en/orm/saving-data.html#converting-belongstomany-data

so in your case tags = users_roles


#8

I’m reading that atm, but I can’t really make anything of it with my current code…