2

編集:私が助けを必要としているのは、topics_posts テーブル内のトピックと投稿の間のすべての関係を削除して、関係をクリーンアップし、古い関係を削除することです。その後、関係を追加する前に関係を削除したため、すべての問題が解決されるため、残りのコードは正常に機能するはずです。

私の CakePHP アプリケーションには、投稿とトピック (トピックは一意で ID があります) があり、投稿とトピックの間の関係を処理する Topic_Posts を介して相互にリンクされています。

ただし、ユーザーが関係を持つ投稿を編集して保存すると、関係を修正するだけでなく、Topic_posts テーブルにそれらが複製され、ユーザーが投稿からトピックを削除しても削除されません!

これに対処する最善の方法は何ですか?その投稿のすべての関係を削除してから再度追加することが、上記のシナリオに対処するための最もクリーンで最良の方法であるという話を聞いたことがありますが、これを行うにはどうすればよいですか?

これは、トピックの保存を処理するコードです (トピックが重複していないことを確認します) が、それらが重複した関係であることを確認せず、関係を削除しません。

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

            // Make it all lowercase for consistency of tag names
            $topic = strtolower($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));
    } 

協会は次のとおりです。

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

    public $belongsTo = 'User';

    public $hasMany = array('Answer');

    // Has many topics that belong to topic post join table... jazz
    public $hasAndBelongsToMany = array(
        'Topic' => array('with' => 'TopicPost')
    );
}

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

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

編集:2つの列を互いに一意にするために、次のことを行いました:

`id` int(11) unsigned NOT NULL auto_increment,
  `topic_id` int(11) NOT NULL,
  `post_id` int(11) NOT NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `unique_row` (`topic_id`,`post_id`)

しかし、更新を行うとSQLエラーが発生するため、基本的にCakeはこれを適切に処理していません...データが繰り返されないようにすることで問題を部分的にしか解決しないため、この問題を修正するにはどうすればよいですか! また、topic_posts からリレーションシップを削除したいのですが、その方法がわからないため、トピックを削除するときにどのように対処すればよいですか?

Database Error
Error: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '2-107' for key 2

SQL Query: INSERT INTO `db52704_favorr`.`topic_posts` (`topic_id`, `post_id`) VALUES (2, 107)
4

1 に答える 1

1

まずid、Topic_Posts の列は必要ありません。それを削除して、代わりにこれを使用する必要があります。

  `topic_id` int(11) NOT NULL,
  `post_id` int(11) NOT NULL,
  PRIMARY KEY  (`topic_id`, `post_id`)

これは、投稿に追加されたすべてのトピックが 1 回しか追加できないことを意味します (これは事実上、現在のものであり、より整然としたものです)。

投稿を更新するときに SQL エラーが発生する理由は、以前に存在したかどうかに関係なく、すべてのトピックを Topic_Posts の投稿に追加しているためです。

コードのスニペットは次のように言っています:

  • ユーザーが投稿に追加したトピックごとに、次の操作を行います。
    • トピックが存在しない場合は、Topic テーブルに追加します (ここで Topic_Posts テーブルに追加するのを忘れているようです)。
    • トピックが存在する場合は、Topic_Posts テーブルに追加します (そこに既に存在するかどうかは確認しません)。

代わりに、次のように伝えます。

  • ユーザーが投稿に追加したトピックごとに、次の操作を行います。
    • トピックが存在しない場合は、Topic テーブルに追加してから Topic_Posts テーブルに追加します (これは Topic_Posts の外部キーであるため、最初に Topic テーブルに作成する必要があります)。
    • トピックが存在する場合...
    • Topic_Posts テーブルにこの投稿が存在しない場合は追加し、そうでない場合は無視します

トピックの削除を処理する別の方法は次のとおりです。

  • 現在の投稿の Topic_Posts からすべての行を削除します
  • ユーザーが投稿に追加したトピックごとに、次の操作を行います。
    • トピックが存在しない場合は、Topic テーブルに追加してから Topic_Posts テーブルに追加します (これは Topic_Posts の外部キーであるため、最初に Topic テーブルに作成する必要があります)。
    • トピックが存在する場合は、Topic_Posts テーブルに追加します

最初のステップは、その投稿のすべてのトピックを削除することであるため、この方法で Topic_Posts にその投稿のトピックが存在するかどうかを確認することについて心配する必要はありません。

それが役立つことを願っています。

于 2012-04-18T23:27:21.440 に答える