How can I delete a join table entry?

I have a site with two models: Site and Photo. They are connected via a belongsToMany association (in both models), so there are 3 tables: sites, photos, and photos_sites.

I want to be able to delete photos, subject to the following rules:
a) If the photo is deleted from one site, and does not appear on any other sites, then it should be deleted entirely. This bit works fine by simply deleting the Photo by id. This also deletes the associated records in photos_sites.
b) If the photo is deleted from one site, and DOES appear on at least one other site, then the photo itself should not be deleted, but the associated record in the join table should be.

Following the official documentation, a) is working fine, but b) is not. For situation b) I have the following:

            $photos_sites = TableRegistry::get('PhotosSites');
            $joinrecord = $photos_sites->find('all')
                                ->where(['PhotosSites.photo_id' => $photo_id, 'PhotosSites.site_id' => $site_id])->first();
            $entity = $this->PhotosSites->get($joinrecord->id);
            $result = $this->PhotosSites->delete($entity);

I’m getting the following error:
Error: Call to a member function get() on a non-object
on the third line above ($entity = …)

I’m also convinced there must be a more efficient way of doing this! What am I doing wrong? Thanks!

Your code is almost correct, you should just be using $photos_sites->get() instead of $this->PhotosSites->get().

You are correct that there is a more efficient way of doing this :slight_smile: Take a look at http://book.cakephp.org/3.0/en/orm/saving-data.html#unlink-many-to-many-records.

Basically, you should/could do:

$this->loadModel('Photos'); //If needed, but ideally this code should be in the PhotosTable as a method to be called
$photo = $this->Photos->get($photo_id);
$site = $this->Photos->Sites->get($site_id);

$this->Photos->unlink($photo, [$site]);

That’s great, thank you!