Рассмотрим следующую схему с пользователями и их коллег (друзей):Как проверить, имеет ли отношение двух записей отношение самореференции?
Пользователи
User:
columns:
user_id:
name: user_id as userId
type: integer(8)
unsigned: 1
primary: true
autoincrement: true
first_name:
name: first_name as firstName
type: string(45)
notnull: true
last_name:
name: last_name as lastName
type: string(45)
notnull: true
email:
type: string(45)
notnull: true
unique: true
relations:
Collegues:
class: User
local: invitor
foreign: invitee
refClass: CollegueStatus
equal: true
onDelete: CASCADE
onUpdate: CASCADE
Регистрация таблице:
CollegueStatus:
columns:
invitor:
type: integer(8)
unsigned: 1
primary: true
invitee:
type: integer(8)
unsigned: 1
primary: true
status:
type: enum(8)
values: [pending, accepted, denied]
default: pending
notnull: true
Теперь, скажем, я две записи, одна для решений пользователя HTTP-запрос (зарегистрированный пользователь) и одна запись для пользователя, которому он хочет отправить сообщение. Я хочу проверить, являются ли эти пользователи коллегами.
Вопросы:
- ли Доктрина есть какие-либо функции предварительной сборки, чтобы проверить, если две записи с связаны с автопортреты отношения?
- Если нет, как бы вы написали метод проверки этого?
- Куда вы поместите указанный метод? (В классе пользователей, UserTable-класс и т.д.)
Я мог бы сделать что-то вроде этого:
public function areCollegues (User $user1, User $user2) {
// Ensure we load collegues if $user1 was fetched with DQL that
// doesn't load this relation
$collegues = $user1->get('Collegues');
$areCollegues = false;
foreach($collegues as $collegue) {
if($collegue['userId'] === $user2['userId']) {
$areCollegues = true;
break;
}
}
return $areCollegues;
}
Но это выглядит ни эффективным, ни достаточно. Я просто чувствую, что он должен быть решен уже для отношений с саморегуляцией, чтобы быть приятным в использовании.
EDIT:
Учитывая, что мы установили следующее UserTable::construct()
:
$this->setAttribute(Doctrine::ATTR_COLL_KEY, 'userId');
Тогда описанный выше метод, вероятно, может быть записано как:
public function areCollegues (User $user1, User $user2) {
// Ensure we load collegues if $user1 was fetched with DQL that
// doesn't load this relation
$collegues = $user1->get('Collegues');
return isset($collegues[$user2['userId']);
}
Это должно быть более эффективным чем первый предложенный метод, но он все равно должен получать (и гидратировать) больше записей, чем хотелось бы.
+1. Я сталкивался с этим раньше, и мне было бы интересно узнать, есть ли более хороший способ сделать это! – richsage