Как проверить, имеют ли две записи ссылку на себя? - PullRequest
2 голосов
/ 08 марта 2010

Рассмотрим следующую схему с пользователями и их коллегами (друзьями):

Пользователи

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 (вошедший в систему пользователь), и одна запись для пользователя, которому он хочет отправить сообщение. Я хочу проверить, являются ли эти пользователи коллегами.

Вопросы:

  1. Имеет ли Doctrine какие-либо функции перед сборкой, чтобы проверить, связаны ли две записи с самоотношениями?
  2. Если нет, то как бы вы написали метод, чтобы проверить это?
  3. Куда бы вы положили указанный метод? (В пользовательском классе, пользовательском классе и т. Д.)

Возможно, я мог бы сделать что-то вроде этого:

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 Ответ

1 голос
/ 08 марта 2010

Может быть, это не то, что вы ищете, но почему бы просто не запросить таблицу? Это намного эффективнее:

$john = // invitor id
$lisa = // invited id
$q = Doctrine_Query::create()
    ->select('c.invitor')
    ->from('CollegueStatus c')
    ->where('c.invitor = ? AND c.invited = ? OR c.invitor = ? AND c.invited = ?, array($john, $lisa, $lisa, $john))
    ->limit(1);
$result = $q->execute(array(), Doctrine_Core::HYDRATE_NONE);
if (!empty($result)) echo 'they are colleagues';

Я предположил, что пользователь может быть либо "приглашенным", либо "приглашенным", следовательно, конструкция AND OR AND.

И вы можете поместить это в метод где угодно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...