Cakephp 模型自身相关,双向

Cakephp 模型自身相关,双向,cakephp,has-many,Cakephp,Has Many,我有一个人员表,其中人员通过id与其他人员关联。我认为这应该使用单独的表来完成,这是此类关系的标准,但我希望在查看单个记录时能够检索关联人员,而不管此记录存储为哪个键。例如: table: people id | first_name | last_name table: people_associations id | person_one_id | person_two_id model: person $hasMany = array( "Associates" => a

我有一个人员表,其中人员通过id与其他人员关联。我认为这应该使用单独的表来完成,这是此类关系的标准,但我希望在查看单个记录时能够检索关联人员,而不管此记录存储为哪个键。例如:

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" => ????
    )
);

如何使
关联
引用关系,无论foreignKey是
person\u one\u id
还是
person\u two\u id
,并在一个整洁的数组中返回所有结果

我相信我成功地实现了一个解决方案。关键部分是使用适当的finderQuery来检查user_关联表中与用户相关的字段,并重新排列“first_id”和“second_id”字段,以确保Cake能够仅使用一个外键字段链接所有关联(本例中为“first_id”)

请注意,我使用了以下表格:

table: users
id | name

table: user_associations
id | first_id | second_id
1。定义用户关联模型

class UserAssociation extends AppModel {

    public $belongsTo = array(
        'Second' => array(
            'className' => 'User',
            'foreignKey' => 'second_id',
        )
    );
}
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 '
        )
    );
}
2。定义用户模型

class UserAssociation extends AppModel {

    public $belongsTo = array(
        'Second' => array(
            'className' => 'User',
            'foreignKey' => 'second_id',
        )
    );
}
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。结果

现在,当我运行以下示例查询时:

$this->User->recursive = 2;
$this->set('user_data', $this->User->read());
我将用户关联作为结果的一部分,并提供相关人员记录-这是视图中捕获的var_dump($user_data)输出:

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)
              ...

希望这有帮助

即使使用
finderQuery
选项,我也尝试了许多关系,但这非常困难。你有没有想过创建两个不同的关系,然后将两个数组合并在一起?@arilia我想这可能就是我的想法。我可以用两种方式保存它(person\u one\u id=1,person\u two\u id=2,然后:person\u one\u id=2,person\u two\u id=1)。不过,我在联接表上还有其他字段,所以它必须在编辑(保存两个关系)和删除(删除两个关系)时执行此操作,但我认为这不会太难。@RandyHall请告诉我这是否适用于您。我会的,这需要做很多工作。我会在未来几天的某个时候实施它,让你知道它是如何进行的!不过看起来不错,谢谢。