使用 Laravel 从表单更新数据库记录

Updating database records from a form using Laravel

提问人:Conlaodh Quinn 提问时间:1/8/2022 最后编辑:lagboxConlaodh Quinn 更新时间:1/8/2022 访问量:1335

问:

我是Laravel的新手,我正在尝试通过表单更新授予人的详细信息,但是数据库表中的记录没有注册任何更改。我已经尝试了许多不同的解决方案,但不幸的是我还没有成功 - 我有一种感觉,问题可能涉及未到达控制器中的更新方法,因为当我在更新方法中放置返回/重定向语句时,这似乎被忽略了。edit 方法似乎可以正常工作,但 update 方法不会更改数据库记录。为了清楚起见,我将包含现有代码的片段。对此问题的任何帮助将不胜感激!

授予者控制器文件

public function update(GrantorRequest $request, $id)
{
    $grantor = Grantor::findOrFail($id);
    $request->validate([
        'grantor_name' => 'required'
    ]);
    $updateDetails = [
        'grantor_name' => $request->get('grantor_name')
    ];
    $grantor->update($updateDetails);
    return redirect()->route('grantors.index');
}

注意“grantor_name”是数据库行中一个字段的示例,还有其他多个字段也需要更新。

Grantors.edit.blade 文件

<div class="flex-1 px-10">
      <form method="PUT" action="{{ route('grantors.update', $grantor->id) }}" class="is-readonly"> 
        
      @method('PATCH')
      @csrf
      

        <div class="row">
            @if ($errors->any()) <span>{{ $errors }}</span> @endif
         </div>
         <div class="h-auto md:h-96">

            <!-- item -->
            <div x-data=" {isOpen : false} " class="pt-2 pb-4 border-b border-divider">
              <div @click="isOpen = !isOpen"
                class="flex items-center cursor-pointer text-neutral-darker hover:text-primary-hover"
                :class="{'font-bold' : isOpen}">
                <span class="text-xl md:xl">Grantor Details</span>
                <img class="mb-1 duration-300 ml-4 inset-0 h-6 w-6" :class="{'transform rotate-180' : isOpen}"
                    src="../../img/icon-arrow-down.png" alt="missing">
              </div>
              <div x-show.transition.duration.300ms.origin.bottom="isOpen" x-cloak @click.away="isOpen = false"
                class="pt-3 text-sm text-neutral">
                @if($is_editable)
                <div class="flex justify-end">
                <button type="button" class="btn btn-default btn-edit js-edit"><img class="mb-1 duration-300 ml-4 inset-0 h-6 w-6" src="../../img/edit-icon.svg" alt="edit"></button>
                <button type="button" class="btn btn-default btn-save js-save"><img class="mb-1 duration-300 ml-4 inset-0 h-6 w-6" src="../../img/save-icon.svg" alt="save"></button>
                </div>
                @endif
                <form class="w-full max-w-sm">
                  <div class="md:flex md:items-center mb-6 ml-6">
                    <div class="md:w-1/7">
                      <label  for="grantor_name" class="block text-neutral-darker font-bold md:text-right mb-1 md:mb-0 pr-4 " for="inline-full-name" disabled>Grantor/ Company/ Organisation Name *
                      </label>
                    </div>
                    <div class="md:w-1/6">
                      <input class="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white focus:border-green-900 is-disabled @error('grantor_name') is-invalid @enderror" name="grantor_name" value="{{ old('grantor_name') ?? $grantor->grantor_name }}" id="grantor_name" type="text" disabled >
                    </div>
                  </div>

租户路由文件

Route::get('/grantors/{id}/edit', [App\Http\Controllers\GrantorController::class, 'edit'])->name('grantors.edit');
Route::put('/grantors', [App\Http\Controllers\GrantorController::class, 'update'])->name('grantors.update');

设保人模型

protected $fillable= [
    'grantor_name'
]);

请注意,$fillable中还包含许多其他字段,出于长度目的,我没有包括这些字段。

PHP 拉维尔

评论

0赞 aynber 1/8/2022
您正在获取模型、验证输入并创建数组,但您从未真正尝试更新模型。
0赞 Conlaodh Quinn 1/8/2022
感谢您的评论,您能否详细说明在这种情况下我将如何正确更新模型?
0赞 lagbox 1/8/2022
是一个 ?此外,方法是从请求中获取输入...你真正想要调用的是非常罕见的,Laravel 出于非常特殊的原因添加了该方法GrantorRequestFormRequest$request->input(....)getinput
0赞 Conlaodh Quinn 1/8/2022
我相信这是一个,我已经用 的语法替换了每个 s,但不幸的是没有区别FormRequestgetinput'grantor_name' => $request->input('grantor_name')

答:

0赞 Mostafa Bahri 1/8/2022 #1

因为你实际上并没有更新模型。您需要调用您的模型:update

    public function update(GrantorRequest $request, $id)
    {
        // Dont do `toArray` . You'll lose the Eloquent model. 
        $grantor = Grantor::findOrFail($id);
        $request->validate([
            'grantor_name' => 'required'
        ]);
        $updateDetails = [
            'grantor_name' => $request->get('grantor_name')
        ];
        // Notice the call below
        $grantor->update($updateDetails);

        return redirect()->route('grantors.index');
    }

路由定义也应更改:

// `id` param was missing
 Route::patch('/grantors/{id}', [App\Http\Controllers\GrantorController::class, 'update'])->name('grantors.update');

而 html 表单不支持 或 method。你应该像下面这样做:patchput

 <form method="POST" action="{{ route('grantors.update', $grantor->id) }}" class="is-readonly"> 
        
      @method('PATCH')
...

评论

0赞 Conlaodh Quinn 1/8/2022
感谢您的评论,我对代码进行了这些修改,但不幸的是,数据库表仍然没有注册任何更改
0赞 Mostafa Bahri 1/8/2022
我更新了我的答案。仔细检查您在 Grantor::class 中。$fillable
0赞 Conlaodh Quinn 1/8/2022
谢谢,是的,我也检查了授予人模型,所有需要的字段都在$fillable
0赞 Mostafa Bahri 1/8/2022
没关系。然后我会说确保控制器真的被击中。在模型更新行之后放一个,让我知道输出。dd($grantor->toArray())
0赞 Conlaodh Quinn 1/8/2022
当我包含没有其他输出时,我仍然被定向到租户文件中指定的 /grantors 页面,而不更新数据库记录dd($grantor->toArray())
0赞 steven7mwesigwa 1/8/2022 #2
  1. 更改您的文件:Grantors.edit.blade.php
<div class="flex-1 px-10">
      <form method="POST" action="{{ route('grantors.update', ['id' => $grantor->id]) }}" class="is-readonly"> 
        
      @method('PUT')
      @csrf
// ...

请注意以下变化:

1a) 至method="PUT"method="POST"

1b) 至@method('PATCH')@method('PUT')

1c) 至{{ route('grantors.update', $grantor->id) }}{{ route('grantors.update', ['id' => $grantor->id]) }}

``

  1. 更改租户路由文件
// ...
Route::put('/grantors/{id}', [App\Http\Controllers\GrantorController::class, 'update'])->name('grantors.update');
// ...

2a) 将该路段包含在路线中。/{id}

  1. 确保您的文件中有一个标签。<form>Grantors.edit.blade.php

从外观上看,您有 2 个标签。一个嵌套在另一个里面。<form>

<form method="PUT" action="{{ route('grantors.update', $grantor->id) }}" class="is-readonly">

<form class="w-full max-w-sm">

  1. 清除路由缓存(如果之前已缓存)。

在终端中,运行以下命令:

php artisan cache:clear

评论

0赞 Conlaodh Quinn 1/8/2022
感谢您的回复,但是当我进行这些更改时出现错误“此路由不支持 POST 方法。支持的方法:GET、HEAD、PUT、PATCH、DELETE。
0赞 steven7mwesigwa 1/8/2022
@ConlaodhQuinn,而不是试试这个:@method('PUT'){{ method_field('PUT') }}
0赞 Conlaodh Quinn 1/8/2022
谢谢,但不幸的是,这样做后,此路由不支持相同的“POST方法。支持的方法:GET、HEAD、PUT、PATCH、DELETE。 返回错误
0赞 steven7mwesigwa 1/8/2022
@ConlaodhQuinn,好的。您能否编辑您的问题并粘贴表单提交的请求正文?
0赞 Conlaodh Quinn 1/8/2022
抱歉,我不确定你所说的请求正文是什么意思,你希望我分享哪个文件?