Список форумов Cake-PHP.ru Cake-PHP.ru
Форум программистов CakePHP
(на сайт)
 
 Watched TopicsWatched Topics   FAQFAQ   ПоискПоиск   ПользователиПользователи   ГруппыГруппы   РегистрацияРегистрация 
 ПрофильПрофиль   Войти и проверить личные сообщенияВойти и проверить личные сообщения   ВходВход 

Ассоциация сама с собой

 
Начать новую тему   Ответить на тему    Список форумов Cake-PHP.ru -> Общий
Предыдущая тема :: Следующая тема  
Автор Сообщение
dedmusos

цитировать



Зарегистрирован: 08 Янв 2008 22:37:19
Сообщения: 8

СообщениеДобавлено: 08 Янв 2008 22:42:27    Заголовок сообщения: Ассоциация сама с собой Ответить с цитатой

Господа, представьте - у нас есть таблица пользователей (users). Теперь перед нами встает задача, создать на сайте такой сервис, как друзья (как на ВКонтакте, грубо). То есть, теперь нам нужно пересвязать элементы таблицы users друг с другом. Получается, что нам нужна доп. таблица friends, но как таковой сущности friends не существует, посему вопрос - как реализовать следующее?

users
id | name |

friends
user_id | friend_id

и связать все это ассоциацией, чтобы иметь возможность во запросу findAll() получить, ко всему прочему, список друзей?

Здесь обязательно создание класса Friend, пусть и фиктивного?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Борис

цитировать



Зарегистрирован: 08 Янв 2008 00:26:04
Сообщения: 8

СообщениеДобавлено: 08 Янв 2008 23:10:40    Заголовок сообщения: Ответить с цитатой

Таблица friends, а лучше friendships, необходима, так как здесь будет связь 1 к n (или даже n к n, если забыть, что друг тоже будет пользователем).

Если бы у каждого человека мог быть только один друг, то есть связь 1 к 1, то достаточно было бы дополнительного поля friend_id в таблице users.

Можно создать "фиктивных" пользователей - друзей других пользователей, но тогда таблица users будет хранить не только пользователей, но и друзей (как отдельных сущностей) всех пользователей, что неверно с точки зрения подхода.

Если бы по человеку надо было находить лишь его друзей, то можно было бы "вывернуться", создав текстовое поле, в которое распаковывать массив друзей. Если я буду другом для своего друга, то есть связь будет двухсторонней, то метод может быть вполне удачным, но реализовать его придётся самому.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
dedmusos

цитировать



Зарегистрирован: 08 Янв 2008 22:37:19
Сообщения: 8

СообщениеДобавлено: 08 Янв 2008 23:56:32    Заголовок сообщения: Ответить с цитатой

Борис
Благодарю, но все вышеописанное Вами мне известно. Считаю, что единственно верный способ с точки зрения БД - это создать таблицу friendships и пересвязать там пользователей как n к n.

Посему вопрос - как реализовать подобную ассоциацию в Cake?
Проблема вот в чем - если пересвязывать как HABTM, то нам обязательно надо будет указать на класс, с которым мы связываем ассоциацию. Можно ли указать собственный класс?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Антон Исайкин
Site Admin
цитировать



Зарегистрирован: 08 Окт 2007 12:02:56
Сообщения: 150
Откуда: Санкт-Петербург

СообщениеДобавлено: 09 Янв 2008 09:09:33    Заголовок сообщения: Ответить с цитатой

Очень знакомая ситуация, реализовывал такое, правда давно. Тогда ничего лучше не придумал, чем в модель user добавить свою функцию вроде такой:
Код:

function getFriends($uid) {
  // тут обращаемся к таблице friends таким запросом
  SELECT user_id, friend_id FROM friends WHERE user_id = $uid OR friend_id = $uid
  // дальше перебираем результат
  $friendIds = array();
  foreach ($result['Friends'] as $row) {
    $friendIds[] = $row['user_id'] == $uid ? $row['friend_id'] : $row['user_id'];
  }
  return $friendIds;
}


Соответственно при добавлении друга проверяем, нет ли уже такой связи.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
dedmusos

цитировать



Зарегистрирован: 08 Янв 2008 22:37:19
Сообщения: 8

СообщениеДобавлено: 09 Янв 2008 14:33:13    Заголовок сообщения: Ответить с цитатой

Антон Исайкин
Идеологически это, конечно, не то, что бы неверно, скажем так - лишено изящности...(((
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Sam Dark

цитировать



Зарегистрирован: 09 Ноя 2007 19:16:48
Сообщения: 19

СообщениеДобавлено: 09 Янв 2008 19:34:15    Заголовок сообщения: Ответить с цитатой

Модель:
Код:
 var $hasAndBelongsToMany = array(
                'Friend' =>
                        array('className' => 'User',
                                        'joinTable' => 'users_users',
                                        'foreignKey' => 'user_id',
                                        'associationForeignKey' => 'friend_id',
                ),
                'Admirer' =>
                        array('className' => 'User',
                                        'joinTable' => 'users_users',
                                        'foreignKey' => 'friend_id',
                                        'associationForeignKey' => 'user_id',
                ),
        );



Контроллер:
Код:
function addfriend($friend_id = null) {
                $this->data = $this->User->read(array('id'), $this->obAuth-

>getUserId());

                $friends = array();
                foreach ($this->data['Friend'] as $friend) {
                        $friends[] = $friend['id'];
                }
                $friends[] = $friend_id;

                $admirers = array();
                foreach ($this->data['Admirer'] as $admirer) {
                        $admirers[] = $admirer['id'];
                }
                $admirers[] = $friend_id;

                unset($this->data['Friend']);
                unset($this->data['Admirer']);

                $this->data['Friend']['Friend'] = $friends;
                $this->data['Admirer']['Admirer'] = $admirers;

                if ($this->User->save($this->data)) {
                        $this->Session->setFlash('Added to Friends.');
                }
        }


Запускаем /users/addfriend/10. 10-ый добавлен к друзьям залогиненого, залогиненый добавлен к друзьям 10-го.

(c) red (english cakephp google group)
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
dedmusos

цитировать



Зарегистрирован: 08 Янв 2008 22:37:19
Сообщения: 8

СообщениеДобавлено: 09 Янв 2008 21:12:05    Заголовок сообщения: Ответить с цитатой

Sam Dark
Красавчик! Люблю профессионалов своего дела...
Самому, право, стыдно, хоть я и третий день кейк изучаю (((
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Антон Исайкин
Site Admin
цитировать



Зарегистрирован: 08 Окт 2007 12:02:56
Сообщения: 150
Откуда: Санкт-Петербург

СообщениеДобавлено: 09 Янв 2008 22:04:14    Заголовок сообщения: Ответить с цитатой

red конечно попал в стиль Cake, но сколь велик смысл дубля всех записей?
А если в результате ошибки из двух записей останется одна? Получится, что Иван федору друг, а вот Федор Ивану -- нет.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Имя
Сообщение

Смайлики
Very Happy Smile Sad Surprised
Shocked Confused Cool Laughing
Mad Razz Embarassed Crying or Very sad
Evil or Very Mad Twisted Evil Rolling Eyes Wink
Exclamation Question Idea Arrow
Дополнительные смайлики

 
Показать сообщения:   
Начать новую тему   Ответить на тему    Список форумов Cake-PHP.ru -> Общий Часовой пояс: GMT + 3
Страница 1 из 1

 
Перейти:  
Вы можете начинать темы
Вы можете отвечать на сообщения
Вы можете редактировать свои сообщения
Вы можете удалять свои сообщения
Вы не можете голосовать в опросах


Powered by phpBB © 2001, 2005 phpBB Group
Русская поддержка phpBB

Рейтинг@Mail.ru