我有以下表格:
用户:
userID
...
课:
lessonID
...
Users_Lessons_Status(充当数据透视表并保存其他信息):
userID references User.userID
lessonID references Lessons.lessonID
latestSectionID
percentComplete
我想要做的是,对于每个用户,每个课程中,数据透视表中应该有一行说明用户在该课程中完成了多少以及他们最新的部分ID是什么。也就是说,应该有userID
和lessonID
(主键?)的唯一对。
我已经设置了我的模型:
<?php
class User extends Eloquent implements UserInterface, RemindableInterface {
...
public function lessonStatuses()
{
return $this->belongsToMany('Lesson', 'users_lessons_status', 'lessonID', 'userID')->withPivot('latestSectionID', 'percentComplete');
}
}
<?
class Lesson extends Eloquent {
protected $table = 'lessons';
protected $primaryKey = 'lessonID';
public function userStatuses()
{
return $this->belongsToMany('User', 'users_lessons_status', 'userID', 'lessonID');
}
}
?>
我目前的路线如下:
Route::post('dbm/users/setLatestSectionID', function() {
if(Auth::check()) {
$user = User::find(Input::get('userID'));
$lesson = Lesson::find(Input::get('lessonID'));
$us = $user->lessonStatuses();
$us->attach($lesson->lessonID,
["latestSectionID" => Input::get('latestSectionID'), "percentComplete" => Input::get('percentComplete')] );
}
});
但是,每次我为同一userID
和lessonID
更新时,它都会创建一个新行,因此该对不再是唯一的。我应该为此目的使用哪种方法?我在文档中尝试了save()
,attach()
和push()
,但我不确定在这里使用哪一个。
修改:澄清一下,结果表应如下所示:
id|userID|lessonID|latestSectionID|percentComplete
1 1 1 X Y
2 1 2
3 1 3
4 2 1
5 3 1
6 3 2
....
修改2 :修正了User->belongsToMany()
方法并添加了withPivot
来电。
答案 0 :(得分:4)
这似乎是一个错误,但你可以做到这一点:
...->sync([$id], false); // detaching set to false, so it will only insert new rows, skip existing and won't detach anything
编辑: 如评论中所述 - 它不适合您,因为您想设置透视数据。 所以基本上没有方法可以做到这一点,但这样的事情应该做:
// belongsToMany.php
public function attachOrUpdate($id, array $attributes = array(), $touch = true)
{
if ($id instanceof Model) $id = $id->getKey();
if ( ! $this->allRelatedIds()->contains($id)) // getRelatedIds() in prior to v5.4
{
return $this->attach($id, $attributes, $touch);
}
else if ( ! empty($attributes))
{
return $this->updateExistingPivot($id, $attributes, $touch);
}
}
我要测试它,如果它通过,发送一个拉请求到4.1
答案 1 :(得分:0)
您应该使用updateExistingPivot()
。
更新您的代码以使用
$us->updateExistingPivot($lesson->lessonID,
["latestSectionID" => Input::get('latestSectionID'), "percentComplete" => Input::get('percentComplete')], true );
最后一个参数将更新所有相关模型的时间戳。如果没有,您可以删除或设置为false。
如果您只想在记录不存在时附加,您可以这样做......
Route::post('dbm/users/setLatestSectionID', function() {
if(Auth::check()) {
$user = User::find(Input::get('userID'));
$lesson = [
"latestSectionID" => Input::get('latestSectionID'),
"percentComplete" => Input::get('percentComplete')
];
$num_lessons = $user->lessonStatuses()->where('id', Input::get('lessonID'))->count();
if($num_lessons == 0) {
$user->attach($lesson->lessonID, $lesson);
} else {
$user->updateExistingPivot($lesson->lessonID, $lesson);
}
}
});
答案 2 :(得分:0)
我最近遇到了这个问题,并以这种方式解决了这个问题:
首先使用updateExistingPivot
并检查结果,如果结果为1
,则意味着存在具有相同的userID
和lessonID
的行,并且已成功更新,否则,如果结果为0
,则表示此userID
和lessonID
没有行,因此您可以附加它以创建新行
$update_result = $us->updateExistingPivot($lesson->lessonID,
["latestSectionID" => Input::get('latestSectionID'), "percentComplete" => Input::get('percentComplete')] );
if($update_result == 0) {
$us->attach($lesson->lessonID,
["latestSectionID" => Input::get('latestSectionID'), "percentComplete" => Input::get('percentComplete')] );
}