【问题标题】:Laravel destroy nested resourceLaravel 销毁嵌套资源
【发布时间】:2021-06-01 05:18:12
【问题描述】:

我有一个资源名称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 (&lt;?php echo $email_domains;?&gt;),那么我得到了预期的结果(请注意,以下是在添加图像之前,因此记录与图像不匹配)

[{"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) 返回这个

正如langbox 状态

(...) hasMany 关系 (...) 所以它返回一个集合 always

所以,灵感来自 this answer from Dan,只是替换

$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);
}

这里有什么问题?

它总是删除上面一行中的记录。

比如我们删除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>

【问题讨论】:

    标签: javascript php laravel eloquent laravel-blade


    【解决方案1】:

    你不能只删除 id,你只传递了 id。

    在控制器中你必须做 Find ,例如:

    $flight = Flight::find($emaidomain);
    

    那你做

    $flight->delete();
    

    你只是在表单中传递了id,你必须通过id找到控制器中的项目然后删除,你不能只删除id。

    【讨论】:

    • 这将得到一个Method Illuminate\Database\Eloquent\Collection::delete does not exist.
    • 确保您添加了模型类,并将示例中的 (Fight) 替换为模型类名称。
    【解决方案2】:

    我已将路线更改为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."));
    }
    

    现在它可以正常工作了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-05
      • 2023-04-02
      • 2012-03-17
      • 2017-12-18
      • 2016-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多