1
votes

to clarify what my problem is, I would like to use the Profile <-> User example from the CakePHP documentation. The relationships defined there are:

  • Profile belongsTo User
  • User hasOne Profile

In the database, the profiles tables has a filed user_id that is used to store the relationship.

In most examples, users set or edit this relationship in the Profile area. Meaning: In the Profile's edit view there is an input field that allows for setting another User for a Profile. It worked automagically by putting the following in the Profiles/edit view:

echo $this->Form->input('user_id');

A change in our rights managment demands us to change the way this relationship can be set. We have to get it out of the Profiles area and instead present it in the Users area.

When reading the data of a User record in the UsersController ($this->request->data = $this->User->read(null, $id);), CakePHP automagically binds the Profile data to the User data (if existent). However, as there is no field profile_id in the users table (because the relationship is stored "on the other side"), obviously echo $this->Form->input('profile_id')); does not work in the Users/edit view.

I already learned that one has to build a list of profiles first in the Controller's edit action:

$this->set('profiles', $this->User->Profile->find('list'));

And then let CakePHP create a select list with:

echo $this->Form->input('Profile');

However, there seems to be something missing. In our case when I look at the HTML output CakePHP creates, several option elements in the select list have the selected attribute set, although there is only one particular profile for a user, and that profile is stored in $this->data.

Somehow I think I have to set some further option(s) in order to get it to work (if there is a way to get it to work automagically – maybe there isn't).

I mean I could set the 'selected' attribute of the Form->input() call. As the name of the form element CakePHP creates is "data[Profile]" I am not sure if CakePHP will automagically save changes correctly, or if I have to do it manually. The steps would be:

  • Look for the (former and still) current profile record having the user_id set to the id of the current user record and set that user_id to 0 (or NULL).
  • Look for the profile with the id set in data[Profile] and set it's user_id to the id of the current user.

But do I have to do it myself, or did I just miss something to enable CakePHP to do it?

2
I'm not sure I understand what you are asking, but instead of $this->Form->input('profile_id')) try $this->Form->input('Profile.id'))arilia
I’m having trouble following too. Are you wanting to keep the User hasOne Profile relationship? Or are you trying to modify it so a User hasMany Profile?Martin Bean
Thanks for taking the time to read, I apologize for the confusion. I want to maintain the hasOne relationship. When I tried $this->Form->input('Profile.id') before, it didn't work as expected (nothing was rendered).Christian Kirchhoff
Meanwhile I learned that I have to feed the input explicitly with the $profiles list (that I set before in the Controller). What's missing now is just that when saving the Profile that had the User.id in its user_id field before has to be unset (or set to 0 or NULL respectively). I selected another profile from the select list for a user, and after saving, that other profile had the User.id written in its user_id field (which is good), but the former Profile's record remained untouched (not so good). But maybe I just have to do it myself…Christian Kirchhoff
probably was rendered an hidden inputarilia

2 Answers

0
votes

I give a try

I don't think you really want to have a select input listing all the profiles you have in your database.

In fact you can edit your User data an his Profile data at the same time:

Let's assume you have address and phone fields in profiles table

you can build a form this way in View/User/edit.ctp:

echo $this->Form->create('User');
echo $this->Form->input('User.name');
echo $this->Form->input('User.family_name');
echo $this->Form->input('Profile.id'); //this is automatically an hidden field
echo $this->Form->input('Profile.address');
echo $this->Form->input('Profile.phone');
echo $this->Form->close();

in your controller you should use

$this->User->saveAssociated($this->request->data);

and User and his Profile will be saved together

Hope this is what you are trying to do.

0
votes

I haven't found any clue that CakePHP would do what I need automatically, so I did it myself as stated above. When saving a user record:

  • Look for the (former and still) current profile record having the user_id set to the id of the current user record and set that user_id to 0 (or NULL).
  • Look for the profile with the id set in data[Profile] and set it's user_id to the id of the current user.