在 Laravel 中更新表单出错

Posted

技术标签:

【中文标题】在 Laravel 中更新表单出错【英文标题】:Updating form in Laravel goes wrong 【发布时间】:2021-07-13 01:52:23 【问题描述】:

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

这是 Laravel 8 中的一个小型 Todo 列表项目 用户可以创建项目。 当用户点击创建的项目时,他会进入项目页面(显示页面)

ShowController.php

public function show(Project $project)
 
    return view('projects.show', compact('project'));
 
在显示页面中,用户可以通过 textarea 表单字段添加 cmets。

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>
问题出在此处,通过更新项目!只要用户在 cmets 字段中输入内容并单击保存,表单就会指示需要以下项目: owner_id、title、description 字段是必需的。而模型被发送到显示刀片页面,然后在表单动作路由中。 我在这里做错了什么?

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

【问题讨论】:

我不明白。为什么“owner_id”、“title”和“description”有必要的规则,而“notes”在表单中只有一个输入?这些数据应该从哪里来?需要输入“title”,但请求中没有“title”,所以验证当然会失败。 感谢您的评论。我只想更新评论!可能吗?我是否必须提出单独的验证请求才能发表评论?我想如果我将项目对象提供给操作表单路由,我将不会遇到验证问题,因为项目对象已经包含“owner_id”、“title”和“description” 这能回答你的问题吗? Laravel form request validation on store and update use same validation @Mohnsen 您可以提出单独的表单请求或确定它是在规则功能内存储还是更新。 @chojnicki 谢谢你的提示。把你的答案放在这里我会检查它作为最佳答案!谢谢 【参考方案1】:

将模型 ID 注入到路由或控制器操作时,您将 经常查询数据库来检索对应的模型 那个身份证。 Laravel 路由模型绑定提供了一种便捷的方式 自动将模型实例直接注入到您的路线中。 例如,您可以不注入用户 ID,而是注入 与给定 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 文件。

【讨论】:

【参考方案2】:

您对表单中不存在的字段具有必需的规则。所以验证正确失败。

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

    制作单独的表单请求文件。所以改为ProjectRequest 为 前任。 ProjectUpdateRequestProjectStoreRequest。 使用单个Request,但在rules()函数中检测是Update还是Store,并根据它返回不同的规则数组。相关问题:Laravel form request validation on store and update use same validation 根本不要使用自定义 FormRequest 进行更新,只需在控制器 update() 函数中进行此单一验证即可。 https://laravel.com/docs/8.x/validation#quick-writing-the-validation-logic

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

【讨论】:

【参考方案3】:

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

【讨论】:

以上是关于在 Laravel 中更新表单出错的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 4 表单验证在更新表单上应该是唯一的,但如果是当前的则不是

Laravel:编辑数据后更新数据库时出错

在 Laravel 的 POST 表单上发送信息时出错

在 LARAVEL 更新表单中使用变量

在 laravel 中更新时,我的选择表单返回 null

更新到 Laravel 5.4 时出错