Laravel 5: 更新多条记录

Laravel 5: Updating Multiple Records

我有一个 Simple Todo 应用程序,它不会同时保存多条记录的更新。客户端版本在这里正常工作:http://codepen.io/anon/pen/bVVpyN

每次执行操作时,我都会向 laravel API 发出一个 http 请求以保存数据。但是我的 completeAll 方法 .

有问题

每当我单击 Complete All 按钮时,我都会执行 completeAll 方法:

completeAll: function () {
    var tasks = [];
    var taskIds = [];

    this.tasks = this.tasks.filter(function (task) {
        task.completed = true;
        tasks.push(task);
        taskIds.push(task.id);
        return task.completed;
    });

    this.$http.put('api/tasks/' + taskIds, { tasks: tasks });
},

在这里,我向 URL 发送请求,可能如下所示:

http://localhost:8000/api/tasks/1,3,8,4

与它一起,我发送了 任务对象。这是来自 chrome 开发者工具的请求负载:

{tasks: [{id: 1, body: "One", completed: true, created_at: "2015-09-09 08:36:38",…},…]}

Then 在服务器端我有一个 update 函数 在我的 TasksController 看起来像这个:

public function update(Request $request, $id)
{
    // gives ["1", "2", "3"] instead of "1,2,3" a
    $taskIds = explode(",", $id);

    // what happens if I update more than one task at once
    // ** PROBLEMATIC SECTION **
    if (count($taskIds) > 1) {
        $tasks = Task::whereIn('id', $taskIds)->get()->toArray();
        $newTasks = Input::get('tasks');

        var_dump($tasks);
        var_dump($newTasks);

        /** This Line does not Work **/
        Task::whereIn('id', $taskIds)->update(Input::get('tasks'));

        return 'update more than one task at once';
    }

    // what happens if I update only one task
    Task::where('id', $id)->update(Input::all());

    return 'update exactly one task';
}

上面的$tasks$newTasks变量var_dump一样,因为我在 $tasks 变量上使用 toArray() 方法。

但是当我尝试更新任务时出现此错误:

preg_replace(): Parameter mismatch, pattern is a string while replacement is an array

不知道为什么。因为在我的理解中 Task::whereIn('id', $taskIds) 是一个对象而不是一个字符串。

到目前为止我尝试过的替代路线

  1. 使用 foreach/for 循环,遍历 $tasks 数组,我无法使其工作,因为我还必须遍历 $newTasks 数组来分配它们,像这样:

    foreach ($tasks as $task) { 对于 ($i=0; $i < count($taskIds); $i++) { Task::where('id', $task->id)->更新($newTasks[$i]) } }

  2. 在我的 API 上创建另一个端点来完成每个任务,URL 像这样:

    http://localhost:8000/api/tasks/complete-all

然后在我的 TasksController 上执行 completeAll 方法,我将每个任务设置为已完成。但是我无法让它工作,因为我得到了

Method not allowed exception

不知道为什么,但我认为最好将我的原始方法与 API 一起使用,如下所示:

api/tasks/1,2,50,1,3

因为这里建议:https://laracasts.com/discuss/channels/code-review/vuejs-delete-multiple-tasks-each-task-one-request


请就我帮助我使这个简单的 TodoApp 工作的最初尝试提出建议。

或者,如果它变得更好,请帮助我使 foreach/for 循环工作。谢谢。


编辑

根据一个答案,建议按照上面的第 2 点创建一个额外的端点。

这些是我的路线:

我对 url:

使用 post 方法
http://localhost:8000/api/tasks/complete-all

通过我的 app.js 执行:

this.$http.post('api/tasks/complete-all');   

这是我改编的 TasksController:

public function completeAll(Request $request)
{
    $tasks = Task::where('completed', false)->get();

    foreach ($tasks as $task) {
       Task::where('id', $task->id)->update(['completed' => true]);
    }

    return response()->json(['message' => 'All tasks completed']);
}

该应用程序现在可以正确保存数据,但令我困扰的是,我并没有真正从客户端更新任何内容。我只是在执行服务器端代码,因为我并没有真正传递任何查询。

我将如何解决问题,使用这样的 URL:

http://localhost:8000/api/tasks/1,23,43,5

谢谢

Laravel CRUD 方法期望在单个资源上。因此,将多个资源发送到 update 不符合此要求。

虽然您可以更新 update 方法,但我鼓励您创建一个 completeTaskscompleteAll 方法来对多个资源进行操作。您可以在请求正文中传递多个资源。

为此,您需要:

  • 添加一个Route
  • 解析 Todo id 的请求数据(就像你 for 循环)
  • 在数据库上调用 update (Task::whereIn('id', $taskIds)->update())