Generic belongsto relation

Hi guys, I’m working on a web application written using cakephp 3.6.

I have the following problem, I have a model that must belongs to one of a variety of other models. For example, the model Alarms must belongs to one of XMachines , YMachines, ZMachines models.

How can I implement this type of relation in cakephp? I know that in other frameworks there is this feature (e.g. django generic relations)

There isn’t a call that would make those connections in a single sweep. But as far as I know there is nothing that would prevent you from making the three association on your Alarms table.

The possible configuration keys for belongTo associations are discussed here.

Your code would look something like this:

// in src/Model/Table/AlarmsTable.php
public function initialize(array $config): void
{
    $this->belongsTo('XMachines', [
        'foreignKey' => 'generic_id',
    ]);
    $this->belongsTo('YMachines', [
        'foreignKey' => 'generic_id',
    ]);
    $this->belongsTo('ZMachines', [
        'foreignKey' => 'generic_id',
    ]);
}

As long as the association names are unique they this would work as far as I know.

The other three models would get associations to Alarms as usual.

I have to admit, I’m scratching my head over how this would work out, but it seems to be what the django method is doing.

Thank you for your help!
I will try your solution tomorrow.
Another question, there’s no a uniquely way to refer to the 3 associations, right? (Something like $alarm->machine)

The actual associations that result from my example code would in the Alarms controller would be:

$this->Alarms->XMachines;
$this->Alarms->YMachines;
$this->Alarms->ZMachines;

From the other sides (the machine side) all the associations could be named the same:

$this->YMachines->Alarms; //etc

You could of course abstract your references to the associated table. Something like this, based on my previous example associations:


foreach (['XMachine', 'YMachine', 'ZMachine'] as $machine ) {
   $this->Alarms->$machine->someMethod();
}

Still, I’m completely mystified about what the use case might be for such a structure :slight_smile:

Later

Ah! Possibly your ids are UUIDs not integers.

The use case is really similar to the example, I have alarms and many types of devices, each with its own table. What i want to achieve is:

  • Given an alarm, determine the device name (or an other property shared by every type of device).
  • Given a device, whatever his type is, retrieve the associated alarms.