Laravel破坏嵌套资源 [英] Laravel destroy nested resource

查看:42
本文介绍了Laravel破坏嵌套资源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个资源名称 OrganizationEmailDomain

  Route :: resource('organizations.emaildomains','OrganizationEmailDomainController',['except'=> ['show']])); 

并且能够对其进行索引

在该视图中,单击三个点时有破坏部分

 < form action =''{{route('organizations.emaildomains.destroy',['organization'=> $ id,'emaildomain'=>> $ email_domain-> id])}}"method ="post">@csrf@method('删除')< button type =按钮"class ="dropdown-item"onclick =" confirm('{{__("您确定要删除此电子邮件域吗?")}}'')吗?this.parentElement.submit():``>{{ __('删除') }}</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}] 

当我试图摧毁

 /***从存储中删除指定的资源.** @param \ App \ OrganizationEmailDomain $ emailDomain* @return \ Illuminate \ Http \ Response*/公共功能destroy(组织$ organization,OrganizationEmailDomain $ emailDomain){//dd($ emailDomain);$ emailDomain-> delete();返回redirect()-> route('organizations.emaildomains.index',$ organization-> id)-> withStatus(__("Organization's email domain included成功删除.")));} 

dd($ emailDomain)返回此

此操作删除了第一行 AAAAAAAAAAAAAAAAA

如果我然后尝试删除 BBBBBBBBBBBBBBB (现在成为第一行),它将删除就可以了.


作为参考,这是index.blade.php,我之前共享的表单位于

 < table class =" table table-flush"id ="datatable-basic"< thead class ="thead-light">< tr>< th范围="col"> {{__('Organization')}}}</th< th范围="col"> {{__('电子邮件域')}}}</th;< th范围="col"> {{__('创建日期')}}}</th;@can('manage-org-emaildomains,App \ User :: class)< th scope ="col">/th@endcan</tr></thead>< tbody>@foreach($ email_domains作为$ email_domain)< tr>< td> {{$ organization->名称}}</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 =下拉">< a class ="btn btn-sm btn-icon-only text-light"href =#"角色=按钮"data-toggle =下拉"aria-haspopup ="true";aria-expanded =假"< i class ="fas fa-省略号-v">/i</a>< div class =下拉菜单-下拉菜单-右键-下拉菜单-箭头">@can('show',$ email_domain)< a class =下拉项目"href =" {{route('organizations.emaildomains.show',['organization'=> $ id,'emaildomain'=> $ email_domain-> id])}}> {{__('显示')}}</a>@endcan@can('update',$ email_domain)< a class =下拉项目"href =" {{route('organizations.emaildomains.edit',['organization'=> $ id,'emaildomain'=> $ email_domain-> id])}}> {{__('编辑')}}</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('删除')< button type =按钮"class ="dropdown-item"onclick =" confirm('{{__("您确定要删除此电子邮件域吗?")}}'')吗?this.parentElement.submit():``>{{ __('删除') }}</button></form>@万一</div></div>@万一</td>@endcan</tr>@endforeach</tbody></table> 

解决方案

我已将路由更改为浅层嵌套

  Route :: resource('organizations.emaildomains','OrganizationEmailDomainController',['except'=> ['show']])-> shallow(); 

然后填写表格

 < form action ="{{route('emaildomains.destroy',['organization'=> $ id,'emaildomain'= >> $ email_domain-> id])}}'";method ="post">@csrf@method('删除')< button type =按钮"class ="dropdown-item";onclick =" confirm('{{__("您确定要删除此电子邮件域吗?")}}'')吗?this.parentElement.submit():``>{{ __('删除') }}</button></form> 

和destroy()

 /***从存储中删除指定的资源.** @param \ App \ OrganizationEmailDomain $ emailDomain* @return \ Illuminate \ Http \ Response*/公共功能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 included成功删除."));} 

现在可以正常工作了.

I have a resource name OrganizationEmailDomain

Route::resource('organizations.emaildomains', 'OrganizationEmailDomainController', ['except' => ['show']]);

and able to index it just fine

In that view, when clicking in the three dots there's the destroy part

<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>

If in that index view I echo $email_domains (<?php echo $email_domains;?>) then I get as expected (note that the following was before the images were added, so the records don't match the images)

[{"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}]

When I try to destroy

/**
 * 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."));
}

that dd($emailDomain) returns this

As langbox states

(...) hasMany relationship (...) so it returns a Collection always

So, inspired in this answer from Dan, just substituted

$emailDomain->delete();

with the following

$org_email = OrganizationEmailDomain::where('id', $organization->org_email_domains->pluck('id'))->delete();

given that in Organization model I have

/**
 * Get the email domains of the organization
 *
 * @return void
 */
public function org_email_domains()
{
    return $this->hasMany(OrganizationEmailDomain::class);
}

What's the problem here?

It always deletes the record that is in the row above.

For example, let's delete DDDDDDDDDDDDDDDDDDD

this deleted the first row, AAAAAAAAAAAAAAAAA

If I then try to delete BBBBBBBBBBBBBBB (which now became the first row) it'll delete just fine.


For reference, here's the index.blade.php where the form I shared previously is at

<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>

解决方案

I've changed the route to shallow nesting

Route::resource('organizations.emaildomains', 'OrganizationEmailDomainController', ['except' => ['show']])->shallow();

then the form to

<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>

and the destroy() to

/**
 * 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."));
}

and now it works fine.

这篇关于Laravel破坏嵌套资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆