CakePHP Получение связанных сообщений из тега - PullRequest
0 голосов
/ 30 июня 2011

У меня три стола

  • сообщения
  • метка
  • posts_tags

Мне нужно написать некоторую логику контроллера, которая выбирает и устанавливает все сообщения с тегом work

Это означает запрос tags для поиска id для запрашиваемого тега, проверка в соответствующей таблице posts_tags для поиска совпадений, использование post_id для возврата правильных сообщений из таблицы сообщений.

Я не уверен, как вообще начать этот запрос, я новичок в CakePHP и могу использовать руку ... Пожалуйста?

Если это поможет, вот мои отношения с моделями сообщений:

var $hasAndBelongsToMany = array(
        'Tag' => array(
            'className' => 'Tag',
            'joinTable' => 'posts_tags',
            'foreignKey' => 'posts_id',
            'associationForeignKey' => 'tag_id',
            'unique' => true,
            'conditions' => '',
            'fields' => '',
            'order' => '',
            'limit' => '',
            'offset' => '',
            'finderQuery' => '',
            'deleteQuery' => '',
            'insertQuery' => ''
        )
    );

Моя таблица тегов состоит из двух полей: id и tag
Моя таблица PostsTag состоит из трех полей: id, tag_id и post_id
Таблица «Мои сообщения» состоит из четырех полей: id, title, body и created

Я нашел некоторый код в Книге CakePHP, который показывает следующий код:

$this->Recipe->Tag->find('all', array('conditions'=>array('Tag.name'=>'Dessert')));

Они предположили, что это была похожая идея, поэтому я попытался приспособиться:

$this->Post->Tag->find('all', array('conditions'=>array('Tag.tag'=>'work')));

Однако это не сработало. Возвращает все сообщения без фильтрации.

Я воспользовался советом @Leo и попытался адаптировать его код к моему:

function getArticleByTagSql($tag) {
        $dbo = $this->getDataSource();
        $subQuery = $dbo->buildStatement(
                        array(
                    'fields' => array('DISTINCT(ArticlesTag.article_id)'),
                    'table' => "articles_tags",
                    'joins' => array(
                        array('table' => 'tags',
                            'alias' => 'Tag',
                            'type' => 'INNER',
                            'conditions' => array('ArticlesTag.tag_id = Tag.id')
                        )
                    ),
                    'alias' => "ArticlesTag",
                    'conditions' => array("Tag.tag" => $tag),
                    'order' => null,
                    'group' => "ArticlesTag.article_id",
                    'limit' => null
                        ), 
                $this
        );
        $subQuery = ' Article.id  IN (' . $subQuery . ')';
        return $dbo->expression($subQuery);
    }

Контроллер:

$this->set('articles', $this->paginate(array(
            'conditions' => $this->Article->getArticleByTagSql('work')
        )));

Однако, что бы я ни вводил в качестве ключа в методе paginate () - в этом случае «условия» появляются в запросе, и я не могу понять, почему - я продолжаю получать неизвестные столбцы «условия» с ошибками. Ошибка в функции paginate, без нее данные возвращаются правильно, но я не могу использовать paginator без нее. Это как улов 22 * ​​1052 *

Приветствия
Dan

Ответы [ 3 ]

2 голосов
/ 30 июня 2011

если вы используете:

$this->Post->Tag->find('all'...

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

tryсделав это вместо этого:

$this->Post->find('all'...

надеюсь, что торт будет достаточно умен (и если вы правильно установили отношения между моделями), чтобы выбрать только посты с тегом "работа" ... и если это не сработает,всегда мог установить соединения "вручную", используя сложное условие поиска

Удачи

1 голос
/ 30 июня 2011

Даниэль, на этот вопрос фактически дан ответ в документации Cake при описании отношений HABTM между Receipe / Tag

I ответил на этот вопрос для кого-то, у кого была похожая проблема с моделями Article / Tag, этот ответ использовал подзапрос

0 голосов
/ 24 августа 2013

У меня была такая же проблема, но я пробовал этот запрос, и он работал для меня ... Может быть, он будет работать и для вас :)

$claims = $this->Claim->query("SELECT DISTINCT Claim.id,Claim.title, Claim.description FROM
             claims as Claim
             LEFT JOIN claim_tags as ClaimTag ON Claim.id = ClaimTag.claim_id
            LEFT JOIN tags as Tag ON Tag.id =ClaimTag.tag_id
            WHERE Tag.id = '$id'");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...