Laravel 中的更新表单出错

Updating form in Laravel goes wrong

这可能是一个很简单的问题,但我想不通!这令人沮丧。 我会尽力一步一步解释一切。

ShowController.php

public function show(Project $project)
 {
    return view('projects.show', compact('project'));
 }

show.blade.php

<form action="{{ route('project.update',['project' => $project]) }}" method="post">
  @csrf
  @method('PUT')
  <textarea name="notes" placeholder="Add notes">{{ $project->notes ?? '' }}</textarea>
  <button type="submit">Save</button>
</form>

UpdateController.php

public function update(ProjectRequest $request, Project $project)
 {
  $validated = $request->validated();
  $project->update($validated);
  return redirect($project->path());
 }

ProjectRequest.php

public function rules(): array
{
  return [
      'owner_id' => 'required',
      'title' => 'required',
      'description' => 'required',
      'notes' => 'nullable',
        ];

web.php

use App\Http\Controllers\Projects\CreateController;
use App\Http\Controllers\Projects\IndexController;
use App\Http\Controllers\Projects\ShowController;
use App\Http\Controllers\Projects\StoreController;
use App\Http\Controllers\Projects\UpdateController;
use Illuminate\Support\Facades\Route;

Route::get('/', [IndexController::class, 'index'])->name('project.index');
Route::get('/projects/create', [CreateController::class, 'create'])->name('project.create');
Route::post('/projects', [StoreController::class, 'store'])->name('project.store');
Route::get('/projects/{project}', [ShowController::class, 'show'])->name('project.show');
Route::put('/projects/{project}', [UpdateController::class, 'update'])->name('project.update');

迁移

 public function up()
    {
        Schema::create('projects', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('owner_id');
            $table->string('title');
            $table->text('description');
            $table->text('notes')->nullable();
            $table->timestamps();

            $table->foreign('owner_id')
                ->references('id')
                ->on('users')
                ->onDelete('cascade');
        });
    }

如果字段不是必需的,那么将它们从 $required 数组中取出,它应该可以工作。

When injecting a model ID to a route or controller action, you will often query the database to retrieve the model that corresponds to that ID. Laravel route model binding provides a convenient way to automatically inject the model instances directly into your routes. For example, instead of injecting a user's ID, you can inject the entire User model instance that matches the given ID. Reference

show.blade.php

<form action="{{ route('project.update',['project' => $project->id]) }}" method="post">
  @csrf
  @method('PUT')
  <textarea name="notes" placeholder="Add notes">{{ $project->notes ?? '' }}</textarea>
  <button type="submit">Save</button>
</form>

此外,要更新列,您不需要验证和更新所有列。

UpdateController.php

  public function update(Request $request, Project $project)
     {
      $request->validate([
            'title' => 'nullable|string',
        ]);
      $project->update(['notes' => $request->notes ?? '']);
      return redirect($project->path());
     }

注:添加使用Illuminate\Http\Request;到第一个 UpdateController.php 文件。

您需要为表单中不存在的字段设置规则。因此正确验证失败。

如果您使用这些规则存储数据,并希望使用不同的规则进行更新,那么您至少有三种解决方案:

  1. 制作单独的表单请求文件。所以改为 ProjectRequest 做 前任。 ProjectUpdateRequestProjectStoreRequest.
  2. 使用单个请求,但在 rules() 函数中检测它是更新还是存储,并且 return 基于它的不同规则数组。相关问题:
  3. 根本不要为更新使用自定义 FormRequest,只需在控制器 update() 函数中进行此单一验证。 https://laravel.com/docs/8.x/validation#quick-writing-the-validation-logic

选项 2 似乎是最佳解决方案,因为您不必在多个地方重复输入“注释”的验证规则 - 所有内容都将在单个文件中。