0

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

そして、New 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)そして私もCakePHP2.1を使用しています

4

1 に答える 1

3

私は次のようなトピック(モデル)でメソッドを実装します:

/**
 * 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

于 2012-04-15T13:47:59.047 に答える