【问题标题】:Laravel edit shallow nested resourceLaravel 编辑浅层嵌套资源
【发布时间】:2021-06-01 23:33:00
【问题描述】:

我正在使用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 匹配。


在 edit.blade.php 我有以下表格来处理更新

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

}

【问题讨论】:

    标签: php laravel laravel-blade laravel-request


    【解决方案1】:

    将模型 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
    

    显示了

    组织/{组织}/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 使用上述建议。

    【讨论】:

    • 谢谢 MrEduar。将尽可能提供赏金。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-02
    • 1970-01-01
    • 2015-11-30
    • 1970-01-01
    • 2014-03-19
    • 1970-01-01
    • 2011-09-19
    相关资源
    最近更新 更多