Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
Vlad
цитировать
Зарегистрирован: 02 Ноя 2007 11:45:52 Сообщения: 241
|
Добавлено: 27 Дек 2008 18:23:14 Заголовок сообщения: Выборка с 2 jointable |
|
|
"не выходит каменный цветок".
Есть Posts (заметки)
Есть Tag (тэги)
Eсть Category (категории)
Posts HABTM Tag jointable Posts_Tags: id post_id, tag_id
Posts HABTM Category jointable Posts_Categories: id, post_id, category_id
ЧТо не получается:
Не получается составить запрос где:
Выбрать все Posts у которых Tag.id => 1, Category.id => 1
Причём важно получить выборку средствами Paginate, ибо через ->find можно немножко извратиться и выбрать несовсем легальным способом, то, что надо. Но хочется получить cakephpшную конструкцию.
Чего только сюда не пихал:
$this->paginate = array("conditions" => ....
Не работает "крошится" и всё, печеньки не выходят.
Как быть? |
|
Вернуться к началу |
|
|
Vlad
цитировать
Зарегистрирован: 02 Ноя 2007 11:45:52 Сообщения: 241
|
Добавлено: 30 Дек 2008 14:14:47 Заголовок сообщения: |
|
|
Люди, ау? Неужели никто никогда не делал и не сталкивался с подобным? |
|
Вернуться к началу |
|
|
evilbloodydemon
цитировать
Зарегистрирован: 11 Окт 2007 20:32:19 Сообщения: 125
|
Добавлено: 30 Дек 2008 15:19:34 Заголовок сообщения: |
|
|
покажи что должно быть и что получается _________________ поздняк метаться - ракеты в воздухе
jabber-конференция по CakePHP - xmpp:cakephp@conference.jabber.ru |
|
Вернуться к началу |
|
|
Vlad
цитировать
Зарегистрирован: 02 Ноя 2007 11:45:52 Сообщения: 241
|
Добавлено: 30 Дек 2008 22:55:56 Заголовок сообщения: |
|
|
Post HABTM Tag
Post HABTM Category
В первом случае используется join_table: posts_tags, во втором categories_posts.
Что мне надо? Мне надо выбрать Все посты, в которых tag = 1, category = 2 (например).
В случае если бы не было Category я бы сделал:
$this->Post->Tag('conditions'... и дальше, как в примере из book.cakephp.org
Однако у меня есть и Tag В и Category
Разумеется, конструкция
$this->Post->Tag->Category работать не будет.
Как мне сделать такую выборку с педжинацией? (all posts where tag = 1 AND Category = 2)
? |
|
Вернуться к началу |
|
|
evilbloodydemon
цитировать
Зарегистрирован: 11 Окт 2007 20:32:19 Сообщения: 125
|
Добавлено: 31 Дек 2008 08:44:18 Заголовок сообщения: |
|
|
а покажите мне sql запрос, который сделает то же самое (даже без паджинации) и при этом вернет каждый пост в единственном экземпляре.
что же можно сделать в реальности, так это выбрать id постов принадлежащих определенным тэгам, потом посты принадлежащие категориям, найти их пересечение и его подставить в условия выборки постов. _________________ поздняк метаться - ракеты в воздухе
jabber-конференция по CakePHP - xmpp:cakephp@conference.jabber.ru |
|
Вернуться к началу |
|
|
Vlad
цитировать
Зарегистрирован: 02 Ноя 2007 11:45:52 Сообщения: 241
|
Добавлено: 31 Дек 2008 10:51:40 Заголовок сообщения: |
|
|
Если бы я знал, как сделать этот запрос...
С пересечением понятно. Значит будет пересечение... |
|
Вернуться к началу |
|
|
Vlad
цитировать
Зарегистрирован: 02 Ноя 2007 11:45:52 Сообщения: 241
|
Добавлено: 31 Дек 2008 11:06:49 Заголовок сообщения: |
|
|
С другой стороны, можно сделать так:
в табличку posts_tags запихнуть 4 поля:
id post_id tag_id category_id
1 1 1 0
2 1 0 2
3 2 2 0
И выгребать из Posts_tags значения подобным запросом:
SELECT post_id
FROM `posts_tags`
WHERE tag_id =1
AND post_id
IN (
SELECT post_id
FROM posts_tags
WHERE category_id =2
)
LIMIT 0 , 30
В результате мы получим искомый post_id = 1.
Осталось придумать, как этот запрос записать в формате Cake, а затем разрулить с точки зрения паджинации.
А заодно проверить, как будет работать HABTM метод с тремя связанными таблицами:
А HABTM B
A HABTM C
B <-> A <-> C
посредством одной связанной таблички posts_tags (в данном случае). |
|
Вернуться к началу |
|
|
Vlad
цитировать
Зарегистрирован: 02 Ноя 2007 11:45:52 Сообщения: 241
|
Добавлено: 05 Янв 2009 02:44:10 Заголовок сообщения: |
|
|
Можно использовать Containable
Код: | $posts = $this->Post->find("all",array("contain" => array("Tag" => array("conditions" => array("Tag.id" => 1)),"Category" => array("conditions" => array("Category.id" => 3))))); |
Но этот запрост отдаст и:
Код: | [2] => Array
(
[Post] => Array
(
[id] => 4
[name] => два два
)
[Tag] => Array
(
)
[Category] => Array
(
)
)
|
ненужные результаты.
А вариант, описанный в book.cake:
$this->Recipe->Tag->find
не сработает, потому как надо писать что-то вроде:
$this->Post->Tag->Category->find - что есть неправильно.
Так же метод:
Код: | $this->Post->bindModel(array('hasOne' => array('PostsTag')));
$posts = $this->Post->find("all",array("fields" => 'Post.*',
'conditions' => array('PostsTag.tag_id' => 1, 'PostsTag.category_id' => 3) |
Не сработает, потому как таблица
posts_tags выглядит так (см. моё письмо выше), что "AND" не сработает, нужен именно "IN"
а запрос захочет:
WHERE `PostsTag`.`tag_id` = 1 AND `PostsTag`.`category_id` = 3
и, естесственно, вернёт пустые результаты
Голову уже сломал |
|
Вернуться к началу |
|
|
Vlad
цитировать
Зарегистрирован: 02 Ноя 2007 11:45:52 Сообщения: 241
|
Добавлено: 05 Янв 2009 02:52:20 Заголовок сообщения: |
|
|
Блин. Разобрался
Уряя!
Завтра отосплюсь - напишу, если конечно, интересно. А то судя по всему - никому неинтересно было |
|
Вернуться к началу |
|
|
timer0x01
цитировать
Зарегистрирован: 01 Ноя 2007 20:28:41 Сообщения: 10
|
Добавлено: 07 Янв 2009 15:25:26 Заголовок сообщения: |
|
|
Vlad, интересно!
Жду ответа ... |
|
Вернуться к началу |
|
|
Vlad
цитировать
Зарегистрирован: 02 Ноя 2007 11:45:52 Сообщения: 241
|
Добавлено: 07 Янв 2009 23:28:59 Заголовок сообщения: |
|
|
На самом деле всё просто оказалось, я невнимательно читал мануал, или, скорее, не понял что этот метод приложим в моём случае.
Итак: Post HABTM Tag, Post HABTM Category
Post (колонки): id, title, body (например)
Tag: id, name
Category: id, name
Связывающие таблицы (2 штуки)
posts_tags: id, tag_id, post_id
categories_posts: id, category_id, post_id
Всё генерится по scaffold-у фактически (т.е. всё просто). Далее, чтобы выбрать все посты с категорий = N, В и тэгом = M
Код: | $this->Post->bindModel(array('hasOne' => array('PostsTag','CategoriesPost')));
$posts = $this->Post->find('all',array('fields' => 'Post.*',
'conditions' => array('PostsTag.tag_id' => 1,'CategoriesPost.category_id' => 4),
)); |
Всё. Телемаркет. В случае с paginate следует указать параметр false в bindMOdel.
Для сокращения потока данных можно поставить recursive = 0, мелочь, а приятно |
|
Вернуться к началу |
|
|
Shiz
цитировать
Зарегистрирован: 27 Май 2008 19:20:34 Сообщения: 10
|
Добавлено: 18 Янв 2009 15:44:37 Заголовок сообщения: |
|
|
Vlad, спасибо, помогло решить похожую проблему=)) _________________ Keep It Simple, Stupid! |
|
Вернуться к началу |
|
|
|