【问题标题】:When I try to detach() is returning the error: local.ERROR: Call to a member function programs() on integer当我尝试 detach() 时返回错误:local.ERROR: Call to a member function programs() on integer
【发布时间】:2019-04-26 17:22:11
【问题描述】:

我在课程和项目之间有这种多对多的关系。我可以插入新课程并添加任意数量的程序,并且它可以正确返回。问题出在更新上。我可以检查我的课程更新表单中的所有数据以及通过选中或取消选中复选框选择的所有程序。

我的想法是当我更新课程时,我想删除所有相关的程序(分离())并根据更新表单中检查的程序再次附加。

当我调用 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!'
    ]);
}

我的课程 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() [堆栈跟踪]

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())并且它正在工作。

有什么想法吗?我试图找到解决方案,但没有任何帮助...

【问题讨论】:

  • 你使用的是什么版本的 Laravel?
  • @RossWilson 这个:Laravel Framework 5.8.13

标签: laravel vue.js


【解决方案1】:

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

【讨论】:

  • 谢谢。此错误消失了,但 detach() 仍然无法正常工作。发生了一些奇怪的事情:如果我更新并检查课程的某些程序,它会在第一次正确显示。如果我再次更新它,新的更改将不适用。让我试着弄清楚并理解它是否来自同一个问题。没有出现错误...
  • 我刚刚测试过,分离和附加工作正常。您的解决方案帮助了我!另一个问题与它无关:)
【解决方案2】:

update() 方法将返回一个boolean 值,因此$course 不会成为您要更新的模型。至于为什么错误是 integer 而不是 boolean 我不是 100% 确定。

有几种解决方案可以获取 corse:

  1. 只需使用find()findOrFail()

    $course = Course::findOrFail($id);
    
  2. 使用Route Model Binding

    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。

【讨论】:

  • 谢谢。但是如果我尝试使用同步,我会得到这个错误:SQLSTATE[42S22]: Column not found: 1054 Unknown column 'description' in 'field list' (SQL: insert into course_program` (course_id, created_at, description, id, is_active, name, pivot, program_id , updated_at) 值 (2, 2019-04-25 01:58:38, asdfdsfsdfsd sdfsfsdf, 3, 1, T768, 2, 0, 2019-04-25 19:08:08)) {"userId": 1,"exception":"[object] ...`。我的数据透视表只有id和时间戳。如何只设置我想要的而不是获取所有数据?
  • 如果我尝试 Route Model Biding,我的行为与使用 $course = Course::findOrFail($id); 相同。这意味着:它仅在第一次更新关联的程序。我会尽力解决这个问题。
  • @GiTavares 我的方法与接受的答案基本相同,所以我不确定为什么你会在$corse-&gt;update(...) 中收到该错误?!?你复制粘贴我的例子了吗?
  • 是的,我做到了。问题不在于$course = Course::findOrFail($id); 作为已接受的答案,它正在工作并且 detach() 的错误消失了。问题在于$course-&gt;programs()-&gt;sync($request-&gt;input('programs', []));。它试图将数据发送到我的数据透视表上不存在的列。在这种情况下,我继续成功使用 detach() 和 attach()。需要明确的是:我的 $request 也有我的课程表和数据透视表的数据。如您所说,使用 sync() 会尝试将所有这些 $request 数据错误地发送到我的数据透视表。
  • @GiTavares 啊,很公平,我认为$request-&gt;programs 只是id 的数组,我现在猜不是。这就是我使用sync() 的原因,因为它最终应该完成与detach()attach() 相同的工作。不管怎样,我很高兴你设法解决了你的问题。
猜你喜欢
  • 1970-01-01
  • 2017-05-16
  • 1970-01-01
  • 2022-12-27
  • 1970-01-01
  • 2018-04-15
  • 2022-12-12
  • 2021-07-24
  • 2022-12-02
相关资源
最近更新 更多