Laravel 销毁嵌套资源
Laravel destroy nested resource
我有一个资源名称 OrganizationEmailDomain
Route::resource('organizations.emaildomains', 'OrganizationEmailDomainController', ['except' => ['show']]);
并且能够很好地对其进行索引
在该视图中,单击三个点时会出现销毁部分
<form action="{{ route('organizations.emaildomains.destroy', ['organization' => $id, 'emaildomain' => $email_domain->id]) }}" method="post">
@csrf
@method('delete')
<button type="button" class="dropdown-item" onclick="confirm('{{ __("Are you sure you want to delete this email domain?") }}') ? this.parentElement.submit() : ''">
{{ __('Delete') }}
</button>
</form>
如果在那个索引视图中我回显 $email_domains (<?php echo $email_domains;?>
) 那么我得到了预期的结果(注意以下是在添加图像之前,所以记录与图片)
[{"id":1,"email_domain":"test.com","organization_id":1,"created_at":"2021-03-02T14:46:50.000000Z","updated_at":"2021-03-02T14:46:56.000000Z"},{"id":2,"email_domain":"gmail.com","organization_id":1,"created_at":null,"updated_at":null}]
当我试图摧毁
/**
* Remove the specified resource from storage.
*
* @param \App\OrganizationEmailDomain $emailDomain
* @return \Illuminate\Http\Response
*/
public function destroy(Organization $organization, OrganizationEmailDomain $emailDomain)
{
//dd($emailDomain);
$emailDomain->delete();
return redirect()->route('organizations.emaildomains.index',$organization->id)->withStatus(__("Organization's email domain successfully deleted."));
}
那个dd($emailDomain)
returns这个
如所述
(...) hasMany relationship (...) so it returns a Collection always
所以,在 的启发下,只需替换
$emailDomain->delete();
与以下
$org_email = OrganizationEmailDomain::where('id', $organization->org_email_domains->pluck('id'))->delete();
考虑到在组织模型中我有
/**
* Get the email domains of the organization
*
* @return void
*/
public function org_email_domains()
{
return $this->hasMany(OrganizationEmailDomain::class);
}
What's the problem here?
它总是删除上一行中的记录。
例如,让我们删除DDDDDDDDDDDDDDDDDDD
这删除了第一行,AAAAAAAAAAAAAAAAA
如果我随后尝试删除 BBBBBBBBBBBBBBB
(现在成为第一行),它会删除得很好。
作为参考,这里是 index.blade.php 我之前分享的表格位于
<table class="table table-flush" id="datatable-basic">
<thead class="thead-light">
<tr>
<th scope="col">{{ __('Organization') }}</th>
<th scope="col">{{ __('Email Domain') }}</th>
<th scope="col">{{ __('Creation date') }}</th>
@can('manage-org-emaildomains', App\User::class)
<th scope="col"></th>
@endcan
</tr>
</thead>
<tbody>
@foreach ($email_domains as $email_domain)
<tr>
<td>{{ $organization->name }}</td>
<td>{{ $email_domain->email_domain }}</td>
<td>{{ $email_domain->created_at ? $email_domain->created_at->format('d/m/Y H:i') : "NULL" }}</td>
@can('manage-org-emaildomains', App\User::class)
<td class="text-right">
@if (auth()->user()->can('update', $email_domain) || auth()->user()->can('show', $email_domain) || auth()->user()->can('delete', $email_domain))
<div class="dropdown">
<a class="btn btn-sm btn-icon-only text-light" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fas fa-ellipsis-v"></i>
</a>
<div class="dropdown-menu dropdown-menu-right dropdown-menu-arrow">
@can('show', $email_domain)
<a class="dropdown-item" href="{{ route('organizations.emaildomains.show', ['organization' => $id, 'emaildomain' => $email_domain->id]) }}">{{ __('Show') }}</a>
@endcan
@can('update', $email_domain)
<a class="dropdown-item" href="{{ route('organizations.emaildomains.edit', ['organization' => $id, 'emaildomain' => $email_domain->id]) }}">{{ __('Edit') }}</a>
@endcan
@if (auth()->user()->can('delete', $email_domain))
<form action="{{ route('organizations.emaildomains.destroy', ['organization' => $id, 'emaildomain' => $email_domain->id]) }}" method="post">
@csrf
@method('delete')
<button type="button" class="dropdown-item" onclick="confirm('{{ __("Are you sure you want to delete this email domain?") }}') ? this.parentElement.submit() : ''">
{{ __('Delete') }}
</button>
</form>
@endif
</div>
</div>
@endif
</td>
@endcan
</tr>
@endforeach
</tbody>
</table>
您不能只删除 ID,您只传递了 ID。
在控制器中你必须做 Find ,例如:
$flight = Flight::find($emaidomain);
然后你做
$flight->delete();
你只是在表单中传递id,你必须通过id在控制器中找到项目然后删除,你不能只删除id。
我已将路线更改为 shallow nesting
Route::resource('organizations.emaildomains', 'OrganizationEmailDomainController', ['except' => ['show']])->shallow();
然后表格到
<form action="{{ route('emaildomains.destroy', ['organization' => $id, 'emaildomain' => $email_domain->id]) }}" method="post">
@csrf
@method('delete')
<button type="button" class="dropdown-item" onclick="confirm('{{ __("Are you sure you want to delete this email domain?") }}') ? this.parentElement.submit() : ''">
{{ __('Delete') }}
</button>
</form>
和 destroy() 到
/**
* Remove the specified resource from storage.
*
* @param \App\OrganizationEmailDomain $emailDomain
* @return \Illuminate\Http\Response
*/
public function destroy(Request $request, OrganizationEmailDomain $emailDomain)
{
$path = $request->path();
$id = substr($path, strrpos($path, '/') + 1);
$emailDomain = OrganizationEmailDomain::find($id);
$emailDomain->delete();
return redirect()->route('organizations.emaildomains.index',$request->query()['organization'])->withStatus(__("Organization's email domain successfully deleted."));
}
现在可以正常使用了。
我有一个资源名称 OrganizationEmailDomain
Route::resource('organizations.emaildomains', 'OrganizationEmailDomainController', ['except' => ['show']]);
并且能够很好地对其进行索引
在该视图中,单击三个点时会出现销毁部分
<form action="{{ route('organizations.emaildomains.destroy', ['organization' => $id, 'emaildomain' => $email_domain->id]) }}" method="post">
@csrf
@method('delete')
<button type="button" class="dropdown-item" onclick="confirm('{{ __("Are you sure you want to delete this email domain?") }}') ? this.parentElement.submit() : ''">
{{ __('Delete') }}
</button>
</form>
如果在那个索引视图中我回显 $email_domains (<?php echo $email_domains;?>
) 那么我得到了预期的结果(注意以下是在添加图像之前,所以记录与图片)
[{"id":1,"email_domain":"test.com","organization_id":1,"created_at":"2021-03-02T14:46:50.000000Z","updated_at":"2021-03-02T14:46:56.000000Z"},{"id":2,"email_domain":"gmail.com","organization_id":1,"created_at":null,"updated_at":null}]
当我试图摧毁
/**
* Remove the specified resource from storage.
*
* @param \App\OrganizationEmailDomain $emailDomain
* @return \Illuminate\Http\Response
*/
public function destroy(Organization $organization, OrganizationEmailDomain $emailDomain)
{
//dd($emailDomain);
$emailDomain->delete();
return redirect()->route('organizations.emaildomains.index',$organization->id)->withStatus(__("Organization's email domain successfully deleted."));
}
那个dd($emailDomain)
returns这个
如
(...) hasMany relationship (...) so it returns a Collection always
所以,在
$emailDomain->delete();
与以下
$org_email = OrganizationEmailDomain::where('id', $organization->org_email_domains->pluck('id'))->delete();
考虑到在组织模型中我有
/**
* Get the email domains of the organization
*
* @return void
*/
public function org_email_domains()
{
return $this->hasMany(OrganizationEmailDomain::class);
}
What's the problem here?
它总是删除上一行中的记录。
例如,让我们删除DDDDDDDDDDDDDDDDDDD
这删除了第一行,AAAAAAAAAAAAAAAAA
如果我随后尝试删除 BBBBBBBBBBBBBBB
(现在成为第一行),它会删除得很好。
作为参考,这里是 index.blade.php 我之前分享的表格位于
<table class="table table-flush" id="datatable-basic">
<thead class="thead-light">
<tr>
<th scope="col">{{ __('Organization') }}</th>
<th scope="col">{{ __('Email Domain') }}</th>
<th scope="col">{{ __('Creation date') }}</th>
@can('manage-org-emaildomains', App\User::class)
<th scope="col"></th>
@endcan
</tr>
</thead>
<tbody>
@foreach ($email_domains as $email_domain)
<tr>
<td>{{ $organization->name }}</td>
<td>{{ $email_domain->email_domain }}</td>
<td>{{ $email_domain->created_at ? $email_domain->created_at->format('d/m/Y H:i') : "NULL" }}</td>
@can('manage-org-emaildomains', App\User::class)
<td class="text-right">
@if (auth()->user()->can('update', $email_domain) || auth()->user()->can('show', $email_domain) || auth()->user()->can('delete', $email_domain))
<div class="dropdown">
<a class="btn btn-sm btn-icon-only text-light" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fas fa-ellipsis-v"></i>
</a>
<div class="dropdown-menu dropdown-menu-right dropdown-menu-arrow">
@can('show', $email_domain)
<a class="dropdown-item" href="{{ route('organizations.emaildomains.show', ['organization' => $id, 'emaildomain' => $email_domain->id]) }}">{{ __('Show') }}</a>
@endcan
@can('update', $email_domain)
<a class="dropdown-item" href="{{ route('organizations.emaildomains.edit', ['organization' => $id, 'emaildomain' => $email_domain->id]) }}">{{ __('Edit') }}</a>
@endcan
@if (auth()->user()->can('delete', $email_domain))
<form action="{{ route('organizations.emaildomains.destroy', ['organization' => $id, 'emaildomain' => $email_domain->id]) }}" method="post">
@csrf
@method('delete')
<button type="button" class="dropdown-item" onclick="confirm('{{ __("Are you sure you want to delete this email domain?") }}') ? this.parentElement.submit() : ''">
{{ __('Delete') }}
</button>
</form>
@endif
</div>
</div>
@endif
</td>
@endcan
</tr>
@endforeach
</tbody>
</table>
您不能只删除 ID,您只传递了 ID。
在控制器中你必须做 Find ,例如:
$flight = Flight::find($emaidomain);
然后你做
$flight->delete();
你只是在表单中传递id,你必须通过id在控制器中找到项目然后删除,你不能只删除id。
我已将路线更改为 shallow nesting
Route::resource('organizations.emaildomains', 'OrganizationEmailDomainController', ['except' => ['show']])->shallow();
然后表格到
<form action="{{ route('emaildomains.destroy', ['organization' => $id, 'emaildomain' => $email_domain->id]) }}" method="post">
@csrf
@method('delete')
<button type="button" class="dropdown-item" onclick="confirm('{{ __("Are you sure you want to delete this email domain?") }}') ? this.parentElement.submit() : ''">
{{ __('Delete') }}
</button>
</form>
和 destroy() 到
/**
* Remove the specified resource from storage.
*
* @param \App\OrganizationEmailDomain $emailDomain
* @return \Illuminate\Http\Response
*/
public function destroy(Request $request, OrganizationEmailDomain $emailDomain)
{
$path = $request->path();
$id = substr($path, strrpos($path, '/') + 1);
$emailDomain = OrganizationEmailDomain::find($id);
$emailDomain->delete();
return redirect()->route('organizations.emaildomains.index',$request->query()['organization'])->withStatus(__("Organization's email domain successfully deleted."));
}
现在可以正常使用了。