Laravel 7 没有只读字段的 FormRequest 更新

Laravel 7 FormRequest update without readonly field

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

问题是如果我使用 ->update() 它根本不工作,没有任何东西提交到数据库,我使用 ->save() 它触发 INSERT 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');

Mass Updates

The update method expects an array of column and value pairs representing the columns that should be updated.

既然你说 "when I update, I don't validate theses fields either I don't refer to them in the update method",你已经在 $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');