Извлечение другой стороны отношений в объекте среднего человека - PullRequest
4 голосов
/ 15 декабря 2011

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

Я работаю над приложением Symfony 2, и у меня есть объекты User, которые должны относиться к другому пользователю, простой вариант использования - это друзья, но есть и более сложные случаи. Изначально у меня были простые отношения между многими, и жизнь была грандиозной.

Теперь мне нужно отследить метаданные о самих отношениях между двумя пользователями, например:

  • когда была запрошена связь
  • когда это было принято
  • когда это закончилось
  • если оно закончилось, существуют ли блоки для предотвращения возобновления этой связи
  • и т.д.

Я провел немало исследований, и, похоже, с Doctrine я не могу получить метаданные о самих отношениях, потому что они не являются сущностями. Было предложено использовать объект среднего уровня, поэтому у пользователей есть отношение многие ко многим с объектом Friendship. Объект дружбы содержит метаданные и ссылки на двух пользователей.

Теперь к моей проблеме, если у меня есть этот объект дружбы, как мне найти другую его сторону? Есть ли у меня функция, которую я передаю известному пользователю, чтобы получить другого пользователя? Один из способов реализовать это приведен ниже, но мне кажется, что должен быть другой способ

$user = $this->getCurrentUser();
$friends = array();
foreach($user->getFriends() as $friendship)
{
    $friends[] = $friendship->not($user); // return the user we dont have
}

и $ дружба-> не ():

public function not($user)
{
    return $this->user1===$user ? $this->user2 : $this->user1;
}

Ответы [ 2 ]

3 голосов
/ 16 декабря 2011

Я решил проблему дружбы пару лет назад.Я не помню всех деталей, но я постараюсь рассказать вам, что я помню.

Прежде всего, посмотрите на этот раздел , в котором написано:

Реальные ассоциации «многие ко многим» встречаются реже.[...]

Почему ассоциации «многие ко многим» встречаются реже?Потому что часто вы хотите связать дополнительные атрибуты с ассоциацией, и в этом случае вы вводите класс ассоциации.Следовательно, прямая ассоциация «многие ко многим» исчезает и заменяется ассоциациями «один ко многим / многие к одному» между 3 участвующими классами.

Итак, у меня было Userи Friendship сущности, которые были сопоставлены с таблицами user и friendship.Последнее выглядело примерно так:

| friendship   |
+--------------+
| from_id      |
| to_id        |
| requested_at |
| accepted_at  | ← if this is not null, then it was accepted

Так как я предпочитаю быть проще, мои User сущности не знали о Friendship сущностях - то есть класс Friendship ссылался наUser класс в однонаправленной манере.В вашем случае это означает, что вы не можете получить список друзей из класса User.Вы, конечно, можете реализовать это так, как это возможно.

Затем у меня был класс FriendshipService (шаблон Service Layer ), в котором был метод, подобный findBy(User $user), который будет делать запрос к базе данных типа «найти всех друзей, где from равно $user или to равно $user».(Возможно, в этом запросе было что-то еще, но я не могу вспомнить.) После того, как у вас есть набор друзей из базы данных, перебирать и перечислять всех друзей тривиально.Вы можете получить другую сторону дружбы, как это:

$otherSide = 
    $friendship->getFrom() == $currentUser ? 
    $friendship->getTo() : 
    $friendship->getFrom();
0 голосов
/ 16 декабря 2011

Если вы храните только ссылки, вы можете поддерживать параллельный массив пользователей и отношений.

$user = $this->getCurrentUser();
$friends[] = $user->getFriends();
$friendships[] = $user->getFriendships();

Где у друзей [0] есть дружба [0] с $ user.

Это довольно стандартный компромисс пространства для скорости, и, конечно, потребуются дополнительные шаги при вставке / удалении и т. Д.

Если вы храните объекты, а не ссылки, это может очень быстро занять много места, и вам будет лучше поддерживать дружеские отношения в виде отдельного списка и искать все дружеские отношения, содержащие $ user.

...