CakePHP 从标签获取关联帖子

发布于 2024-11-17 22:35:56 字数 2921 浏览 2 评论 0原文

我有三个表

  • 帖子
  • 标签
  • posts_tags

我需要编写一些控制器逻辑来选择和设置具有标签 work 的所有帖子

这意味着查询 tags 以查找 < code>id 作为查询标签,检查关联的 posts_tags 表以查找匹配项,使用 post_id 从 posts 表返回正确的帖子。

我不知道如何开始这个查询,我是 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' => ''
        )
    );

我的标签表由两个字段组成:idtag
我的 PostsTag 表由三个字段组成:idtag_idpost_id
我的帖子表由四个字段组成:idtitlebodycreated

我在上面找到了一些代码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() 方法中输入什么作为键 - 在这种情况下,“条件”出现在查询中,我无法弄清楚为什么 - 我不断收到未知列“条件”错误。错误在于分页函数,没有它数据会正确返回,但如果没有它我就无法使用分页器。这就像捕获 22

干杯,

I've got three tables

  • posts
  • tags
  • posts_tags

I need to write some controller logic that selects and sets all posts that have the tag work

This means querying the tags to find the id for the queried tag, checking in the associated posts_tags table to find matches, using the post_id to return the correct posts from the posts table.

I'm not sure how to even begin this query, I'm new to CakePHP and could use a hand... Please?

If it helps, here's my posts model relationship:

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' => ''
        )
    );

My Tag table is made up of two fields: id and tag
My PostsTag table is made up of three fields: id, tag_id and post_id
My Posts table is made up of four fields: id, title, body and created

I found some code on the CakePHP Book that shows the below code:

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

They suggested that it was a similar idea, so I attempted to adapt:

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

However, this has not worked. This returns all Posts without filtering.

I took the advice of @Leo and tried to adapt his code to mine:

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);
    }

Controller:

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

However, whatever I type in the paginate() method as a key - in this case 'conditions' appears in the query and I can't figure out why - I keep getting unknown column 'conditions' errors. The error is with the paginate function, the data returns correctly without it, but I cannot use the paginator without it. It's like a catch 22

Cheers,
Dan

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

过气美图社 2024-11-24 22:35:56

如果你使用:

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

你告诉他找到所有标签都有效...并且由于它是递归的,每个标签将包含相关的帖子..

尝试这样做:

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

希望蛋糕足够聪明(并且如果你正确设置了你的模型关系)仅选择具有“工作”标签的帖子..如果这不起作用,您始终可以使用 复杂查找条件

祝你好运

if you use:

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

you're telling him to find all Tags work... and since its recursive, each tag will contain the related posts..

try doing this instead:

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

hopefully cake will be smart enough (and if you have correctly set your models relations) to only select posts that have the "work" tag.. and if that doesnt work, you could always set the joins "manually" using a complex find condition

Good Luck

紙鸢 2024-11-24 22:35:56

Daniel 这个问题实际上在 Cake 文档 描述 HABTM 之间的关系时得到了回答收据/标签

I 为遇到类似问题的人回答了这个问题文章/标签模型,该答案使用了子查询

Daniel this question is actually answered in the Cake documentation when describing the HABTM relationship betweens Receipe/Tag

I answered this question for someone who had a similar issue with an Article/Tag models, that answer used a subquery

怪我太投入 2024-11-24 22:35:56

我遇到了同样的问题,但我尝试了这个查询,它对我有用......也许它也对你有用:)

$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'");

I had same problem, but I tried this query and it worked for me...May be it will work for you too :)

$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'");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文