Laravel 中的更新表单出错
Updating form in Laravel goes wrong
这可能是一个很简单的问题,但我想不通!这令人沮丧。
我会尽力一步一步解释一切。
- 这是 Laravel 8
中的一个小型待办事项列表项目
- 用户可以创建项目。
- 当用户点击创建的项目时,他会进入项目页面(显示页面)
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>
- 错误就在这里,通过更新项目!用户在评论字段中输入内容并单击保存后,表单会立即指示以下项目是必需的:
- owner_id、标题、描述字段为必填项。同时将模型发送到显示 blade 页面,然后在表单操作路由中。
我在这里做错了什么?
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 文件。
您需要为表单中不存在的字段设置规则。因此正确验证失败。
如果您使用这些规则存储数据,并希望使用不同的规则进行更新,那么您至少有三种解决方案:
- 制作单独的表单请求文件。所以改为
ProjectRequest
做
前任。 ProjectUpdateRequest
和 ProjectStoreRequest
.
- 使用单个请求,但在
rules()
函数中检测它是更新还是存储,并且 return 基于它的不同规则数组。相关问题:
- 根本不要为更新使用自定义 FormRequest,只需在控制器
update()
函数中进行此单一验证。
https://laravel.com/docs/8.x/validation#quick-writing-the-validation-logic
选项 2 似乎是最佳解决方案,因为您不必在多个地方重复输入“注释”的验证规则 - 所有内容都将在单个文件中。
这可能是一个很简单的问题,但我想不通!这令人沮丧。 我会尽力一步一步解释一切。
- 这是 Laravel 8 中的一个小型待办事项列表项目
- 用户可以创建项目。
- 当用户点击创建的项目时,他会进入项目页面(显示页面)
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>
- 错误就在这里,通过更新项目!用户在评论字段中输入内容并单击保存后,表单会立即指示以下项目是必需的:
- owner_id、标题、描述字段为必填项。同时将模型发送到显示 blade 页面,然后在表单操作路由中。 我在这里做错了什么?
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 文件。
您需要为表单中不存在的字段设置规则。因此正确验证失败。
如果您使用这些规则存储数据,并希望使用不同的规则进行更新,那么您至少有三种解决方案:
- 制作单独的表单请求文件。所以改为
ProjectRequest
做 前任。ProjectUpdateRequest
和ProjectStoreRequest
. - 使用单个请求,但在
rules()
函数中检测它是更新还是存储,并且 return 基于它的不同规则数组。相关问题: - 根本不要为更新使用自定义 FormRequest,只需在控制器
update()
函数中进行此单一验证。 https://laravel.com/docs/8.x/validation#quick-writing-the-validation-logic
选项 2 似乎是最佳解决方案,因为您不必在多个地方重复输入“注释”的验证规则 - 所有内容都将在单个文件中。