如何仅显示表中没有HABTM关联的行

时间:2014-07-15 13:59:45

标签: php mysql cakephp has-and-belongs-to-many

我有一个新闻Feed应用程序我正在写作,我想找出一种方法,可以将每篇新闻文章标记为已经过"查看"每个用户单独。我想要实现的当前方法是将articles_users表中的任何行视为含义"此用户已查看过此文章"如果他们有一个条目,则将其当前user_id与当前article_id相关联。

这是我到目前为止所拥有的......

在我的Article模型中:

App::uses('AuthComponent', 'Controller/Component');

class Article extends AppModel {

    public $hasAndBelongsToMany = array(
        'User' => array(
            'className' => 'User',
            'joinTable' => 'articles_users',
            'foreignKey' => 'article_id',
            'associationForeignKey' => 'user_id',
            'unique' => true
        )
    );

    public $findMethods = array('available' =>  true);

    protected function _findAvailable($state, $query, $results = array()) {
        if ($state === 'before') {
            $limit = (Configure::read('AppSettings.itemsperpage') ? Configure::read('AppSettings.itemsperpage'): '8');
            $query['limit'] = $limit;
            $query['order'] = 'Article.listdatetime DESC';
            if (!empty($query['operation']) && $query['operation'] === 'count') {
                return $query;
            }
            $query['joins'] = array(
                array(
                    'table' => 'articles_users',
                    'alias' => 'ArticlesUser',
                    'type' => 'INNER',
                    'conditions' => array(
                        'ArticlesUser.user_id' => CakeSession::read("Auth.User.id"),
                        'ArticlesUser.article_id <> Article.id'
                    )
                )
            );
            $query['group'] = 'Article.id';
            return $query;
        }
        return $results;
    }

    public $validate = array(
        'title' => array(
            'required' => array(
                'rule' => array('notEmpty'),
                'message' => 'A title is required'
            )
        ),
        'permalink' => array(
            'required' => array(
                'rule' => array('notEmpty'),
                'message' => 'A permalink is required'
            )
        ),
        'feed' => array(
            'required' => array(
                'rule' => array('notEmpty'),
                'message' => 'A feed is required'
            )
        )
    );

}

在我的ArticlesController中:

public function index() {
    $this->paginate = array('available');
    $articles = $this->paginate();
    $this->set(compact('articles'));
}

导出articles_users表格的结构和内容:

--
-- Table structure for table `articles_users`
--

CREATE TABLE IF NOT EXISTS `articles_users` (
`id` int(11) NOT NULL,
  `article_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;

--
-- Dumping data for table `articles_users`
--

INSERT INTO `articles_users` (`id`, `article_id`, `user_id`) VALUES
(2, 3266, 4);

但是,尽管article_id 3266与user_id 4相关联,但我仍然看到该文章出现,因为条件我ArticlesUser.article_id <> Article.id(不等于)。在我的index()方法/操作中,我怎么才能只显示没有与当前article_id关联的user_id的文章?

1 个答案:

答案 0 :(得分:0)

感谢franglais的评论。如果其他人有这个问题,我现在正在使用它:

protected function _findAvailable($state, $query, $results = array()) {
    if ($state === 'before') {
        $limit = (Configure::read('AppSettings.itemsperpage') ? Configure::read('AppSettings.itemsperpage'): '8');
        $query['limit'] = $limit;
        $query['order'] = 'Article.listdatetime DESC';
        if (!empty($query['operation']) && $query['operation'] === 'count') {
            return $query;
        }
        $query['joins'] = array(
            array(
                'table' => 'articles_users',
                'alias' => 'ArticlesUser',
                'type' => 'INNER',
                'conditions' => array(
                    'ArticlesUser.user_id' => CakeSession::read("Auth.User.id"),
                    'ArticlesUser.article_id <> Article.id'
                )
            )
        );
        $query['group'] = 'Article.id';
        return $query;
    }
    return $results;
}