【问题标题】:Eloquent's fillable not working with mutatorsEloquent 的可填充不能与 mutators 一起使用
【发布时间】:2020-11-13 00:48:57
【问题描述】:

我有以下型号:

<?php

namespace App;

use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;

class PaymentOption extends Model
{
    protected $table = 'payment_option';
    public $timestamps = false;
    protected $fillable = ['payment_option_code', 'payment_option_name'];

    public function setCodeAttribute($value) 
    {
        $this->attributes['payment_option_code'] = $value;
    }

    public function getCodeAttribute()
    {
        return $this->payment_option_code;
    }

    public function setNameAttribute($value)
    {
        $this->attributes['payment_option_name'] = $value;
    }

    public function getNameAttribute($value)
    {
        $this->payment_option_name;
    }
}

如您所见,我的列名很奇怪。我需要修改器,因为我将接受没有前缀 payment_option 的变量。

现在,我在我的控制器中这样做:

<?php

namespace App\Http\Controllers;

use App\PaymentOption;
use App\Http\Requests\PaymentOptionRequest;

class PaymentOptionController extends Controller
{
    private $paymentOption;

    public function __construct(PaymentOption $paymentOption)
    {
        $this->paymentOption = $paymentOption;
    }


    public function create(PaymentOptionRequest $request)
    {
        $paymentOption = $this->paymentOption->fill($request->validated());

        dump($paymentOption);

        return response()->json([]);
    }
}

当我尝试使用 fill() 时,它不会调用 mutators。但是当我尝试将其设置为 1 比 1 时,它的工作方式如下:

$paymentOption->code = $validated['code'];

为什么会这样?

谢谢!

【问题讨论】:

  • 我认为 fill 根本无法与 mutators 一起使用,因为 fill 来自 EloquentQueryBuilder,而您在 PaymentOption 上定义了 mutators。
  • 尝试使用create而不是fill
  • 这在 Laravel 5.8 中确实有效。同样的实例化new Model(['foo'=&gt;'bar]) 在升级到 Laravel 6.x 后它停止为我工作。我倾向于不使用fillable,而是在一些列上使用protected

标签: laravel eloquent laravel-7


【解决方案1】:

在 laravel 8 的最新版本中,fill 的实现发生了变化。在 laravel 旧版本中,fill 方法对 mutator 和数据库列都有效。但是在 laravel 8 中,fill 方法的实现现在更改了 fill 还要检查数组中给定的 key fill 方法是否是数据库列。 例如,如果您有数据库列名称 user_idmutator 名称是 user 它不适用于 laravel 8。它适用于旧版本的 laravel。

如果$guarded 数组至少包含一个列/键,那么 Eloquent 模型将进入严格模式,它只能填充有效数据库列的值。这是官方代码库中为此编写的测试(link to test)。

要解决问题,请使用forceFill。这将解决您的问题。

【讨论】:

    【解决方案2】:

    fill 会在 $fillable 数组中的输入数据上循环

     public function fill(array $attributes)
    {
        $totallyGuarded = $this->totallyGuarded();
    
        foreach ($this->fillableFromArray($attributes) as $key => $value) {
            $key = $this->removeTableFromKey($key);
    
            // The developers may choose to place some attributes in the "fillable" array
            // which means only those attributes may be set through mass assignment to
            // the model, and all others will just get ignored for security reasons.
            if ($this->isFillable($key)) {
                $this->setAttribute($key, $value);
            } elseif ($totallyGuarded) {
                throw new MassAssignmentException(sprintf(
                    'Add [%s] to fillable property to allow mass assignment on [%s].',
                    $key, get_class($this)
                ));
            }
        }
    
        return $this;
    }
    

    因此,您需要将“代码”和“名称”添加到可填充数组中以由填充分配它们

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-04
      • 2014-03-20
      • 1970-01-01
      • 2015-09-11
      • 1970-01-01
      相关资源
      最近更新 更多