问题
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