我在课程和程序之间具有这种多对多关系。我可以插入新课程并添加任意数量的程序,并且可以正确返回。问题在更新上。我可以将“课程更新”表单中的所有数据以及通过复选框选中或取消选中的所有程序感染。
我的想法是,当我更新课程时,我想删除所有相关程序(detach()),然后根据更新表格中选中的程序再次附加。
当我调用update方法并调用detach()时会发生问题。
我的模特是:
课程(模型):
class Course extends Model
{
protected $fillable = [
'name', 'title', 'description', 'is_active'
];
public function programs(){
return $this->belongsToMany(Program::class)->withTimestamps();
}
}
程序(模型):
class Program extends Model
{
protected $fillable = [
'name', 'description', 'is_active'
];
public function courses(){
return $this->belongsToMany(Course::class)->withTimestamps();
}
}
我对CoursesController的更新:
public function update(Request $request, $id)
{
$request->validate([
'name' => 'required',
'title' => 'required'
]);
// $course = Course::whereId($id)->update($request->all());
$course = Course::whereId($id)->update([
'name' => $request->name,
'title' => $request->title,
'description' => $request->description,
'is_active' => $request->is_active
]);
$course->programs()->detach();
$program = Program::find($request->programs);
$course->programs()->attach($program);
return response()->json([
'course' => $course,
'message' => 'Course has been Updated!'
]);
}
我的Course Vuejs组件:
<template>
...
</template>
<script>
export default {
data(){
return {
course:{
name: '',
title: '',
description: '',
is_active: true,
programs: []
},
courses: [],
uri: 'http://127.0.0.1:8000/courses/',
errors: [],
new_update_course: [],
toastr: toastr.options = {"positionClass": "toast-top-full-width"},
programs: [],
uriPrograms: 'http://127.0.0.1:8000/activePrograms/',
}
},
methods: {
...
loadUpdateCourseModal(index){
this.errors = [];
$("#update-course-modal").modal("show");
this.new_update_course = this.courses[index];
this.new_update_course.programs.forEach(program => {
this.new_update_course.programs.push(program.id)
});
},
...
updateCourse(){
axios.patch(this.uri + this.new_update_course.id, {
name: this.new_update_course.name,
title: this.new_update_course.title,
description: this.new_update_course.description,
is_active: this.new_update_course.is_active,
programs: this.new_update_course.programs
}).then(response =>{
$("#update-course-modal").modal("hide");
toastr.success(response.data.message);
}).catch(error=>{
if(error.response.data.errors.name){
this.errors.push(error.response.data.errors.name[0]);
}
if(error.response.data.errors.title){
this.errors.push(error.response.data.errors.title[0]);
}
if(error.response.data.errors.description){
this.errors.push(error.response.data.errors.description[0]);
}
});
},
...
},
mounted(){
...
}
}
</script>
例如,如果我尝试更新id = 2的课程,例如在我的laravel日志中,则错误是:
local.ERROR:在整数{“ userId”:1,“ exception”:“ [object](Symfony \ Component \ Debug \ Exception \ FatalThrowableError(code:0)”上调用成员函数programs()在/Users/GiselleTavares/Documents/.../app/Http/Controllers/CoursesController.php:120上的整数上的成员函数programs() [stacktrace]
0 [内部功能]:App \ Http \ Controllers \ CoursesController-> update(Object(Illuminate \ Http \ Request),'2')
CoursesController.php:120的行是:
$course->programs()->detach();
我不明白此错误的含义...
在整数上调用成员函数programs()...
如果我在下面对这3行进行评论,则可以更新课程数据,但是,当然,无需更改程序关系...
$course->programs()->detach();
$program = Program::find($request->programs);
$course->programs()->attach($program);
如果我仅评论detach()行,attach()行将显示与上面相同的错误。但是,我在store()上使用了完全相同的东西(没有detach()),并且可以正常工作。
有什么想法吗?我试图找到解决方案,但无济于事...
答案 0 :(得分:2)
update()
函数returns an integer指示是否更新(这是批量更新,因为Course::whereId($id)
返回的是结果集合,而不是单个结果)一个)。
这应该有效:
$course = Course::findOrFail($id);
$course->update([
'name' => $request->name,
'title' => $request->title,
'description' => $request->description,
'is_active' => $request->is_active
]);
答案 1 :(得分:0)
update()
方法将返回一个boolean
值,因此$course
不会成为您要更新的模型。至于为什么错误是说integer
而不是boolean
,我不确定100%。
有两种解决方案可以得到答案:
只需使用find()
或findOrFail()
$course = Course::findOrFail($id);
public function update(Request $request, Course $course)
以选项1为例,您的代码将类似于:
public function update(Request $request, $id)
{
$request->validate([
'name' => 'required',
'title' => 'required',
]);
$course = Course::findOrFail($id);
$course->update([
'name' => $request->name,
'title' => $request->title,
'description' => $request->description,
'is_active' => $request->is_active,
]);
$course->programs()->sync($request->input('programs', []));
return response()->json([
'course' => $course,
'message' => 'Course has been Updated!',
]);
}
在上面的示例中,我使用了sync()而不是分离并附加新的ID。