Изменить: мне нужна помощь в том, что вы удаляете все отношения между темой и сообщением в таблице themes_posts, чтобы очистить отношения и удалить старые. Тогда остальная часть кода ДОЛЖНА работать нормально, так как все проблемы будут устранены, потому что мы удалили отношения до их добавления.
В моем приложении CakePHP у меня есть сообщения и темы (темы уникальны и имеют идентификатор), и они связаны друг с другом через Topic_Posts, который обрабатывает отношения между сообщением и темой.
Однако, если пользователь редактирует сообщение, у которого есть отношения, и они сохраняют его, вместо того, чтобы просто корректировать отношения, он будет дублировать их в таблице Topic_posts, а также не удаляет их, если пользователь удаляет тему из сообщения!
Каков наилучший способ справиться с этим? Я слышал разговоры об удалении ВСЕХ отношений для этого сообщения, а затем повторное добавление их – это самый чистый и лучший способ справиться с указанным сценарием, но опять же, как мне это сделать?
Это код, который обрабатывает сохранение тем (который проверяет, что темы НЕ дублируются), но не проверяет, что они дублируются отношения. NOR устраняет отношения.
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' ); }
EDIT: Я сделал следующее, чтобы сделать два столбца уникальными друг против друга:
`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)
Прежде всего вам не нужен id
столбца в Topic_Posts. Вы должны удалить его и вместо этого использовать это:
`topic_id` int(11) NOT NULL, `post_id` int(11) NOT NULL, PRIMARY KEY (`topic_id`, `post_id`)
Это будет означать, что каждая тема, добавленная в сообщение, может быть добавлена только один раз (это действительно то, что у вас есть сейчас, только намного более аккуратное).
Причина, по которой вы получаете ошибку SQL при обновлении сообщения, заключается в том, что вы добавляете каждую тему в сообщение в Topic_Posts независимо от того, существовали они раньше или нет.
В вашем фрагменте кода говорится:
Вместо этого вы хотите сказать что-то вроде этого:
Альтернативный способ справиться с устранением тем может быть:
Вам не нужно беспокоиться о проверке того, существует ли тема для этой публикации в Topic_Posts таким образом, поскольку первым шагом является удаление всех тем для этой публикации.
Надеюсь, это поможет.