【问题标题】:Saving tags into a database table in CakePHP在 CakePHP 中将标签保存到数据库表中
【发布时间】:2012-04-15 11:26:03
【问题描述】:

我的 CakePHP 应用程序有以下设置:

Posts
id
title
content

Topics
id
title

Topic_Posts
id
topic_id
post_id

所以基本上我有一个主题(标签)表,它们都是唯一的并且有一个 id。然后可以使用 Topic_Posts 连接表将它们附加到帖子。当用户创建新帖子时,他们将通过将主题输入到以逗号分隔的文本区域来填写主题,然后如果它们不存在,则将它们保存到主题表中,然后将引用保存到 Topic_posts 表中。我的模型设置如下:

后模型:

class Post extends AppModel
{
    public $name = 'Post';

    public $hasAndBelongsToMany = array(
        'Topic' => array('with' => 'TopicPost')
    );
}

主题模型:

class Topic extends AppModel
{
    public $hasMany = array(
        'TopicPost'
    );
}

TopicPost 模型:

class TopicPost extends AppModel {
    public $belongsTo = array(
        'Topic', 'Post'
    );
}

到目前为止,对于新的 post 方法,我有这个:

public function add()
{
    if ($this->request->is('post'))
    {
        //$this->Post->create();

        if ($this->Post->saveAll($this->request->data))
        {

            // Redirect the user to the newly created post (pass the slug for performance)
            $this->redirect(array('controller'=>'posts','action'=>'view','id'=>$this->Post->id));
        }
        else
        {
            $this->Session->setFlash('Server broke!');
        }
    }
}

如您所见,我使用了saveAll,但我该如何处理主题数据?

我见过类似的东西:http://bakery.cakephp.org/articles/dooltaz/2007/05/02/simple-tagging-behavior,但我希望这样做更简单、更现代(那篇文章日期为 2007 年),而且我也在使用 CakePHP 2.1

【问题讨论】:

    标签: php cakephp


    【解决方案1】:

    我会像这样在主题(模型)中实现一个方法:

    /**
     * This methods saves the topics coming from a post save and associates them with the right post.
     * 
     * @param string $postId The post id to save associations to.
     * @param string $topics A comma seperated list of topics to save.
     * @param bool Save of all topics succeeded (true) or not (false).
     */
        public function savePostTopics($postId, $topics){
            // Explode the topics by comma, so we have an array to run through
            $topics = explode(',', $topics);
            // Array for collecting all the data
            $collection = array();
    
            foreach($topics as $topic){
                // Trim it so remove unwanted white spaces in the beginning and the end.
                $topic = trim($topic);
    
                // Check if we already have a topic like this
                $controlFind = $this->find(
                    'first',
                    array(
                        'conditions' => array(
                            'title' => $topic
                        ),
                        'recursive' => -1
                    )
                );
    
                // No record found
                if(!$controlFind){
                    $this->create();
                    if(
                        !$this->save(
                            array(
                                'title' => $topic
                            )
                        )
                    ){
                        // If only one saving fails we stop the whole loop and method.
                        return false;
                    }
                    else{
                        $temp = array(
                            'TopicPost' => array(
                                'topic_id' => $this->id,
                                'post_id' => $postId
                            )
                        )
                    }
                }
                else{
                    $temp = array(
                        'TopicPost' => array(
                            'topic_id' => $controlFind['Topic']['id'],
                            'post_id' => $postId
                        )
                    )
                }
                $collection[] = $temp;
            }
    
            return $this->TopicPost->saveMany($collection, array('validate' => false));
        }
    

    我没有测试它,但它应该可以工作。

    您可以在保存帖子本身后调用它,并为其提供帖子 ID 和数据数组中的主题。确保您处理该方法的返回。如果主题保存失败,这是删除整个帖子的原因吗?由于 cakephp 中没有很好的实现回滚 api,但如果需要,您可能必须从数据库中删除帖子。或者你只是给写帖子的用户一个成功的信息并记录错误?

    顺便说一句:按照 cakephp 约定,模型和关联表也必须命名为 PostTopicpost_topic。按字母顺序;) 您可能希望在项目的早期阶段更改它。

    问候 func0der

    【讨论】:

    • 效果很好。不过,我不必更改任何表名或模型名吗?谢谢;)
    • 不,您不必更改它。但是按照 cakephp 约定,您应该;)通读:book.cakephp.org/2.0/en/models/…(示例下方的信息框)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多