首页 > 解决方案 > Laravel 7 FormRequest 更新没有只读字段

问题描述

我有一个模型,创建后您无法修改某些数据。考虑到这一点,当我更新时,我不会验证这些字段,也不会在更新方法中引用它们。

问题是,如果我使用->update()它根本不工作,没有任何东西被提交到数据库,我使用->save()它 fireINSERT INTO而不是UPDATE.

我不明白到底发生了什么。谢谢你。

模型

class Profile extends Model
{
    use Userstamps;
    use SoftDeletes;

    protected $fillable = [
        'name',
        'street_address',
        'street_address2',
        'city',
        'province',
        'postal_code',
        'phone',
        'email',
        'url',
        'description',
        'logo_path',
    ];

    protected $guarded = [
        'active',
        'created_by',
        'modified_by',
    ];

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function user ()
    {
        return $this->belongsTo(User::class);
    }

    /**
     * @return bool
     */
    public function canModify ()
    {
        return ((auth()->user()->role === 'admin') || ($this->created_by === auth()->user()->id));
    }

}

表单请求

class UpdateProfile extends FormRequest
{
    public function rules ()
    {
        $rules = [
            'name'            => 'required',
            'street_address'  => 'required',
            'street_address2' => 'nullable',
            'city'            => 'required',
            'province'        => 'required',
            'postal_code'     => 'required|regex:/^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ]( )?\d[ABCEGHJKLMNPRSTVWXYZ]\d$/|size:7',
            'phone'           => 'nullable|regex:/^1\s\(\d{3}\)\s\d{3}-\d{4}$/|size:16',
            'email'           => 'required|email:rfc,dns,spoof|unique:App\User,email',
            'url'             => 'nullable|url',
            'description'     => 'nullable',
            'logo_path'       => 'nullable',
        ];

        return $rules;
    }
}

控制器

class ProfileController extends Controller
{
    public function update (Profile $profile, UpdateProfile $request)
    {
        if (!$profile->canModify()) {
            return redirect('profiles')
                ->with('error.message', __('app.restricted', [
                    'title' => request("name"),
                ]));
        }

        $update                     = $request->validated();
        $profile['name']            = $update['name'];
        $profile['street_address']  = $update['street_address'];
        $profile['street_address2'] = $update['street_address2'];
        $profile['city']            = $update['city'];
        $profile['province']        = $update['province'];
        $profile['postal_code']     = $update['postal_code'];
        $profile['phone']           = $update['phone'];
        $profile['email']           = $update['email'];
        $profile['url']             = $update['url'];
        $profile['description']     = $update['description'];
        if (isset($update['logo_path'])) {
            $profile['logo_path'] = $request->file('logo_path')->store('uploads/logos');
        }

        $profile->update();

        return redirect()
            ->route('profiles', $profile)
            ->with('saved.message', __('profile.message.edited', [
                'title' => $profile->name,
            ]));
    }
}

路线

Route::get('/profile/{profile}/edit', 'ProfileController@edit')
    ->name('profile.edit')
    ->middleware('auth');

Route::put('/profile/update', 'ProfileController@update')
    ->name('profile.update')
    ->middleware('auth');

标签: laraveleloquentlaravel-7

解决方案


大规模更新

update 方法需要一个表示应该更新的列的列和值对数组。

既然你说“当我更新时,我不会验证这些字段,也不会在更新方法中引用它们”,你已经在$update变量中有那个数组,我认为你可以这样做:

public function update (Profile $profile, UpdateProfile $request)
{
    if (!$profile->canModify()) {
        return redirect('profiles')
            ->with('error.message', __('app.restricted', [
                'title' => request("name"),
            ]));
    }

    $update = $request->validated();
    if (isset($update['logo_path'])) {
        $update['logo_path'] = $request->file('logo_path')->store('uploads/logos');
    }

    $profile->update($update);

    return redirect()
        ->route('profiles', $profile)
        ->with('saved.message', __('profile.message.edited', [
            'title' => $profile->name,
        ]));
}

此外,您需要在路由上声明一个参数以使用模型绑定来更新控制器上的现有记录:

Route::put('/profile/{profile}/update', 'ProfileController@update')
    ->name('profile.update')
    ->middleware('auth');

推荐阅读