Model related to itself, bi-directional

本秂侑毒 提交于 2020-01-15 09:23:27

问题


I have a people table, where people are associated with other people by id. I believe this should be done with a separate table as is standard for such relationships, but I want to be able to retrieve the associated people when viewing a single record regardless of which key this record was stored as. For instance:

table: people
id | first_name | last_name

table: people_associations
id | person_one_id | person_two_id

model: person
$hasMany = array(
    "Associates" => array(
        "className" => "Person",
        "foreignKey" => ????
    )
);

How do I make this so that Associates references the relationship whether the foreignKey is person_one_id or person_two_id, and return all the results in one neat array?


回答1:


I believe I managed to implement a solution. The key part is to use a proper finderQuery which checks both user related fields in the user_association table and it also rearranges the "first_id" and "second_id" fields order to make sure Cake is able to link all associations using just one foreign key field ("first_id" in this example).

Please note I used the following tables:

table: users
id | name

table: user_associations
id | first_id | second_id

1. Define UserAssociation model

class UserAssociation extends AppModel {

    public $belongsTo = array(
        'Second' => array(
            'className' => 'User',
            'foreignKey' => 'second_id',
        )
    );
}

2. Define User model

class User extends AppModel {

    //fields definition skipped for brevity

    public $hasMany = array(
        'UserAssociations' => array(
            'className' => 'UserAssociation',
            'foreignKey' => 'first_id',
            'finderQuery' => 'SELECT * FROM (SELECT UserAssociations.id, UserAssociations.first_id, UserAssociations.second_id 
                FROM user_associations as UserAssociations 
                WHERE (UserAssociations.first_id = {$__cakeID__$})
                UNION 
                SELECT UserAssociations2.id, UserAssociations2.second_id as first_id, UserAssociations2.first_id as second_id 
                FROM user_associations as UserAssociations2 
                WHERE (UserAssociations2.second_id = {$__cakeID__$}) ) as UserAssociations '
        )
    );
}

3. Result

Now, when I run a sample query as follows:

$this->User->recursive = 2;
$this->set('user_data', $this->User->read());

I get UserAssociations as a part of the result with related people records available - this is the var_dump($user_data) output as captured in a view:

array (size=3)
  'User' => 
    array (size=2)
      'id' => string '1' (length=1)
      'name' => string 'John Doe' (length=8)
  'UserAssociations' => 
    array (size=2)
      0 => 
        array (size=4)
          'id' => string '1' (length=1)
          'first_id' => string '1' (length=1)
          'second_id' => string '18' (length=2)
          'Second' => 
            array (size=2)
              ...
      1 => 
        array (size=4)
          'id' => string '2' (length=1)
          'first_id' => string '1' (length=1)
          'second_id' => string '17' (length=2)
          'Second' => 
            array (size=2)
              ...

Hope this helps!



来源:https://stackoverflow.com/questions/20832098/model-related-to-itself-bi-directional

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!