У меня есть две таблицы, то есть комментарии и рейтинги. Таблица комментариев имеет первичный ключ ['comment_id','source_id']
а таблица Рейтинги имеет первичный ключ ['comment_id','source_id','topic_id']
,
Модельные отношения определены ниже:
/* Model comments Table*/
$this->table('comments');
$this->primaryKey(['comment_id','source_id']);
$this->hasMany('Ratings',[
'foreignKey'=>['comment_id','source_id']
]);
/* Model Ratings Table*/
$this->table('ratings');
$this->primaryKey(['comment_id','source_id','topic_id']); // Notice the primary key has 3 columns
$this->belongsTo('Comments',[
'foreignKey'=>['comment_id','source_id']
]);
Я хочу вставить несколько комментариев, и каждый комментарий будет иметь несколько оценок, связанных с ним, разные оценки под каждым комментарием относятся к разным темам оценки. Я пытаюсь сохранить комментарий и связанные с ним оценки, используя синтаксис saveMany, но cakePHP сохраняет комментарий правильно, но оба рейтинга не сохраняются, а только последний рейтинг.
/* Inside controller's action */
$comment['comment_id'] = '12';
$comment['source_id'] = 4;
$comment['travel_date'] = '';
$comment['ratings'] = [
[ //This doesn't gets saved
'topic_id' =>5,
'rating' =>4,
'created' =>'2017-02-09 13:06:04'
],
[ //This gets saved
'topic_id' =>6,
'rating' =>5,
'created' =>'2017-02-09 13:06:04'
]];
$multipleRows[0] = $comment;
$newRows = $this->Comments->newEntities($multipleRows,['associated' => ['Ratings']]);
$this->Comments->saveMany($newRows);
Я сделал журнал SQL и нашел это:
Отладка: длительность = 0 строк = 0 НАЧАЛО
Отладка: длительность = 1 строк = 0 ВЫБРАТЬ 1 AS
existing
ОТ комментариев как
комментарии ГДЕ (comments.comment_id = ’12’ И comments.source_id = 4)
LIMIT 1Отладка: длительность = 1 строк = 1 INSERT INTO комментарии (comment_id, source_id,
travel_date) VALUES (’12’, 4, »)Отладка: длительность = 1 строк = 0 ВЫБРАТЬ 1 AS
existing
ОТ рейтингов как
рейтинги ГДЕ (rating.comment_id = ’12’ И рейтинги.source_id = 4)
LIMIT 1Отладка: длительность = 1 строка = 1 INSERT INTO рейтинги (comment_id, source_id,
topic_id, рейтинг, создан) ЗНАЧЕНИЯ (’12’, 4, 5, 4, ‘2017-02-09
13:06:04’ )Отладка: длительность = 1 ряд = 1 ВЫБРАТЬ 1 AS
existing
ОТ рейтингов как
рейтинги ГДЕ (rating.comment_id = ’12’ И рейтинги.source_id = 4)
LIMIT 1Отладка: длительность = 1 ряд = 1 ОБНОВЛЕНИЕ рейтингов SET topic_id = 6, рейтинг = 5
, создал = ‘2017-02-09 13:06:04′ ГДЕ (comment_id = ’12’ И
source_id = 4)Отладка: длительность = 0 строк = 0 COMMIT
Если вы видите вышеупомянутый журнал, CakePHP проверяет наличие дубликатов и, если запись уже существует, он обновляет запись, а не добавляет новую строку. Но проблема здесь в том, что для этой проверки CakePHP использует только внешний ключ, а не первичный ключ целевой таблицы. В моем случае первичный ключ содержит 3 столбца, и первые 2 столбца из них составляют внешний ключ. Как я могу исправить эту проблему и вставить несколько оценок в таком сценарии?
Я уже искал на SO и тоже погуглил. Найденные решения удовлетворяют моему случаю. Мой случай отличается, так как таблица рейтингов имеет 3 столбца составного первичного ключа и из этих 3 первые 2 являются внешним ключом для таблицы комментариев.
Задача ещё не решена.
Других решений пока нет …