如何解决Laravel 编辑浅层嵌套资源
我使用以下资源使用 shallow nesting
Route::resource('organizations.emaildomains','OrganizationEmailDomainController',['except' => ['show']])->shallow();
得到以下包含两条记录的表格,这是 index.blade.PHP 的结果
假设我们要将 tiagoperes.eu
编辑为 stackoverflow.com
。我会转到编辑视图
更改相应的字段并单击保存按钮。这是结果
如您所见,记录未更新。
检查控制器 update() 中的 $request->all()
以及网络标签中的表单数据
并将数据发布到
http://localhost/app/public/emaildomains/7
与浅嵌套中的 URI 匹配。
<form method="post" action="{{ route('emaildomains.update',['emaildomain' => $email_domain->id]) }}" autocomplete="off">
@csrf
@method('put')
<h6 class="heading-small text-muted mb-4">{{ __('Email Domain information') }}</h6>
<div class="pl-lg-4">
<div class="form-group{{ $errors->has('organization_id') ? ' has-danger' : '' }}">
<label class="form-control-label" for="input-organization_id">{{ __('Organization') }}</label>
<select name="organization_id" id="input-organization" class="form-control{{ $errors->has('organization_id') ? ' is-invalid' : '' }}" placeholder="{{ __('Organization') }}" required>
@foreach ($organizations as $organization)
<option value="{{ $organization->id }}" {{ $organization->id == old('organization_id',$email_domain->organization->id) ? 'selected' : '' }}>{{ $organization->name }}</option>
@endforeach
</select>
@include('alerts.Feedback',['field' => 'organization_id'])
</div>
<div class="form-group{{ $errors->has('email_domain') ? ' has-danger' : '' }}">
<label class="form-control-label" for="input-email_domain">{{ __('Email Domain') }}</label>
<input type="text" name="email_domain" id="input-email_domain" class="form-control{{ $errors->has('email_domain') ? ' is-invalid' : '' }}" placeholder="{{ __('Email Domain') }}" value="{{ old('email_domain',$email_domain->email_domain) }}" required autofocus>
@include('alerts.Feedback',['field' => 'email_domain'])
</div>
<div class="text-center">
<button type="submit" class="btn btn-success mt-4">{{ __('Save') }}</button>
</div>
</div>
</form>
这里是 OrganizationEmailDomainController
/**
* Show the form for editing the specified resource.
*
* @param \App\OrganizationEmailDomain $email_domain
* @return \Illuminate\Http\Response
*/
public function edit(Request $request,OrganizationEmailDomain $email_domain,Organization $model)
{
$path = $request->path();
$id = (int)explode('/',$path)[1];
$emailDomain = OrganizationEmailDomain::find($id);
return view('organizations.emaildomains.edit',['email_domain' => $emailDomain->load('organization'),'organizations' => $model::where('id',$emailDomain->organization_id)->get(['id','name'])]);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\OrganizationEmailDomain $email_domain
* @return \Illuminate\Http\Response
*/
public function update(Request $request,OrganizationEmailDomain $email_domain)
{
$email_domain->update($request->all());
$organization_id = (int)$request->all()['organization_id'];
return redirect()->route('organizations.emaildomains.index',['organization' => $organization_id])->withStatus(__("Org's email domain successfully updated."));
}
这是模型(请注意,我使用的表的名称与默认情况下的预期名称不同 - protected $table = 'email_domains';
)
class OrganizationEmailDomain extends Model
{
protected $fillable = [
'email_domain','organization_id'
];
protected $table = 'email_domains';
/**
* Get the organization
*
* @return \Organization
*/
public function organization()
{
return $this->belongsTo(Organization::class);
}
}
解决方法
将模型 ID 注入路由或控制器操作时,您通常会查询数据库以检索与该 ID 对应的模型。 Laravel 路由模型绑定提供了一种便捷的方式来自动将模型实例直接注入到你的路由中。例如,您可以注入与给定 ID 匹配的整个 OrganizationEmailDomain 模型实例,而不是注入 OrganizationEmailDomain 的 ID。
Laravel 自动解析在路由或控制器操作中定义的 Eloquent 模型,这些模型的类型提示变量名称与路由段名称匹配。例如:
use App\OrganizationEmailDomain;
Route::put('emaildomains/{emailDomain}',[OrganizationEmailDomainController::class,'update']);
那么以下应该在你的控制器中
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\OrganizationEmailDomain $emailDomain
* @return \Illuminate\Http\Response
*/
public function update(Request $request,OrganizationEmailDomain $emailDomain)
{
$emailDomain->update($request->all());
return redirect()->route('organizations.emaildomains.index',[
'organization' => $request->organization_id
])->withStatus(__("Org's email domain successfully updated."));
}
注意,如果变量名 $emailDomain
与路由段 {emailDomain}
不同,那么 Laravel 将无法解析模型。因此,您将获得一个空的 OrganizationEmailDomain 模型,它不会更新任何数据。所以一定要在路由中定义相同的名称。
要检查哪个是正确的路线名称,请运行命令 php artisan route:list
,您将看到路线和路段名称。
编辑
为了解决问题,我跑了
php artisan route:list
显示
organizations/{organization}/emaildomains/{emaildomain} | Organizations.emaildomains.update
因此,将 OrganizationEmailDomainController.php
更改为
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\OrganizationEmailDomainRequest $request
* @param \App\OrganizationEmailDomain $emaildomain
* @return \Illuminate\Http\Response
*/
public function update(OrganizationEmailDomainRequest $request,OrganizationEmailDomain $emaildomain)
{
$emaildomain->update($request->all());
return redirect()->route('organizations.emaildomains.index',['organization' => $request->organization_id])->withStatus(__("Org's email domain successfully updated."));
}
足够了。
请注意,控制器中唯一需要的更改是从 $email_domain
到 $emaildomain
,但还删除了不必要的位以获取组织 ID,并使用上面通过 $request 建议的方法。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。