CakePHP 3.x Saving new record but also new associated record

786 Views Asked by At

So I'm developing a system where a user can create a new account and upload a profile photo. I'm using two models: User for the account, Photo for the photos.

The users table has a foreign key on the field photoId that references to photos.id. The photos table has a userId field that has a foreign key referencing users.id. So there is a recursive relationship between User and Photo. Reason for this: when a Photo is created, we want to be able to see which User uploaded the Photo. A User has one Photo as his profile image.

So it's Photo hasOne User and User hasOne Photo. They are also configured this way in their Table classes.

Now, when a new User is saved, we want to also save a new Photo. Photo needs the id of the newly created User in order to save, but the User needs the id of the newly created Photo.

My question: what is the best method to save this? Should we allow User.photoId to be null, so that we can first save the User, then save the Photo, and then update the User with the correct Photo.id, or can CakePHP3 do some magic where it does all of this linking back and forth for you?

Data that comes from the form:

[
    'username' => 'John Doe',
    'mail' => '[email protected]',
    'password' => 'whatever',
    'photo' => [
        'name' => 'myImage.jpg',
        'type' => 'image/jpeg',
        'tmp_name' => '/private/var/tmp/phpN3dVmL',
        'error' => (int) 0,
        'size' => (int) 40171
    ]
]
2

There are 2 best solutions below

4
On

Make Things Simple !

Why you need hasOne relations for both table ?

It looks like you are making simple thing so complected.Let's talk about that:

You have two tables users and photos that's fine.
At the moment each user has one photo that's fine as well.

Just imagine one day user might have multiple photo, then ?

Then still no worries, everything would be good because you have photos table already.

So what kind of relations do you actually need here ?

Just like mentioned above, user has one photo, That's why relation should be:
user hasOne photo and obviously photo belongsTo user.

And you need nothing more than that.

Just for example

Fields on Users table

id
name
email
address
has_photo // eg:if has_photo = 1 user has uploaded photo,such field is not compulsary
password...etc

Fields on Photos table

id
user_id // foreign key of users table
name
size

Relations

// UsersTable.php
  $this->hasOne('Photos', [
      'foreignKey' => 'user_id'
  ]);

 // PhotosTable.php
  $this->belongsTo('Users', [
        'foreignKey' => 'user_id',
        'joinType' => 'INNER'
    ]);

Don't be confuse on that photos need user_id..users table never need photo_id.Because users table already associated with photos table. And if A hasOne B then B obviously belongs to A.That's the simple logic.

Don't hesitate to see the documentation ( Associations ) to get more information on relations..This is really important things for database management.

2
On

or can CakePHP3 do some magic where it does all of this linking back and forth for you?

Yes! As long as your associations are setup correctly Cake will take care of the rest. So the best method is to pass your data array into newEntity or patchEntity and make sure that all passed fields are accessible in you entity.

Saving hasOne relationships

Entities and mass assignment