在 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
为
前任。 ProjectUpdateRequest
和 ProjectStoreRequest
。
使用单个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 中更新表单出错的主要内容,如果未能解决你的问题,请参考以下文章