We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

One-to-one relationship through an intermediate table

My data has a one-to-one relationship between a CourseAdd model, and it's EventType model. However, the data in those tables don't interact with each other - they both relate back to a row in the event table.

I have created a many-to-many relationship like so:

$this->hasManyToMany(
            'event_id',
            '\Model\Event',
            'id','type',
            '\Model\EventType',
            'name',
            ['alias'=>'Type']
        );

This is successfully setting up the relationship, but the problem is that it's not set up as a single entity, but rather a collection. So in CourseAdd, $this->Type references a simple resultset. To reference the particular record, I have to go $this->Type[0].

Is there a way to set up a one-to-one relationship, but specifying it through an intermediary table? Looking at the Zephyr source code, it appears there are references to "has-one-through", but I don't see any subsequent methods to call.

Hi @Dylan do you try with params in relation options?

public function initialize() {
  $this->hasManyToMany(
    'event_id',
    '\Model\Event',
    'id','type',
    '\Model\EventType',
    'name',
    [
      'alias'=>'Type',
      'params' => [
          'limit' => 1 // one-to-one
      ]
    ]
  );
}

public function getType() {
    return $this->getRelated('Type')->getFirst();
}

public function setType($type) {
    $this->Type[0] = $type;
}

With that you can simulate a one-to-one.

I hope it helps. Good luck



9.7k

Is there any other code using the components of the relationship? Do they check/protect the one-to-one relationship? Things could be messy if one bit of code assumes one-to-one while another bit allows a many-to-one connection.

Hi @Dylan do you try with params in relation options?

public function initialize() {
 $this->hasManyToMany(
  'event_id',
  '\Model\Event',
  'id','type',
  '\Model\EventType',
  'name',
  [
    'alias'=>'Type',
    'params' => [
        'limit' => 1 // one-to-one
    ]
  ]
 );
}

public function getType() {
  return $this->getRelated('Type')->getFirst();
}

public function setType($type) {
  $this->Type[0] = $type;
}

With that you can simulate a one-to-one.

I hope it helps. Good luck

I added the params option, but it didn't change the data structure at all. I tried looking for other options other than alias but I wasn't able to find any documentation. Could you provide a link?

edited Oct '17

Is there any other code using the components of the relationship? Do they check/protect the one-to-one relationship? Things could be messy if one bit of code assumes one-to-one while another bit allows a many-to-one connection.

I don't anticipate this relationship being used for anything other than read-only. And since this is technically a kind of many-to-one relationship, the assumption will always be that "Type" should be a single record.

Well the only doc about is model relationship. The params option was in post on blog but paginations now is broken. But basically you can pass in params the same parameters what use in find()/findFirst() just limit conditions order etc...

I hope it helps you

Have a look at this blog post (yeah I know I need to fix the pagination for the blog)

https://blog.phalcon.io/post/phalcon-2-0-4-released

It outlines the relationships with parameters