如果插入期间不在表中,则Laravel Eloquent会忽略属性

dan*_*gel 10 php laravel

我有一个模型Foo,对应于一个包含以下列的表.

id
描述
user_id

我正在单独设置Foo模型的属性(没有质量分配)

$foo = new Foo;

$foo->id = 1;
$foo->description = "hello kitty";
$foo->user_id = 55;

//...
Run Code Online (Sandbox Code Playgroud)

$ foo被发送到另一个类进行额外处理,但由于该类需要更多信息,我想简单地将它添加到$ foo模型中.

//...
$foo->bar = $additional_information;

Event::fire(DoStuffWithFoo($foo));

$foo->save();  //error
Run Code Online (Sandbox Code Playgroud)

问题是当我$foo->save(),它抱怨bar不是一个专栏.

我知道我可以unset($foo->bar);在保存之前,但......

是否可以告诉Eloquent简单地忽略任何不相关的属性?

Ada*_*dam 10

只需$bar在您的foo类中添加为属性即可:

class Foo extends Model
{

  public $bar;
  //...
Run Code Online (Sandbox Code Playgroud)

现在您可以使用了save(),Laravel不会尝试将其存储bar在数据库中。


说明:

如果调用save()模型,则只会将数组中的那些属性$model->attributes保存到数据库中。如果$bar在类中定义为属性Foo,则$foo->bar ="xyz"永远不会在数组中结束$model->attributes

但是,如果尚未为声明此类属性Foo,则会__set()调用,因为您尝试将某些内容保存在不可访问的属性中

您可以签出Laravel\Illuminate\Database\Eloquent\Model.php

/**
     * Dynamically set attributes on the model.
     *
     * @param  string  $key
     * @param  mixed  $value
     * @return void
     */
    public function __set($key, $value)
    {
        $this->setAttribute($key, $value);
    }
Run Code Online (Sandbox Code Playgroud)

基本上是

$this->attributes[$key] = $value;
Run Code Online (Sandbox Code Playgroud)

来自 Laravel\Illuminate\Database\Eloquent\Concerns\HasAttributes.php

现在$foo->bar ="xyz"最终会陷入困境$foo->attribute['bar'],这就是为什么save()崩溃的原因..this column does not exists..

  • 我希望这对我有用,但它就是行不通。我有一个属性不在表中,但它是 getBarAttribute。无论我在调用 $model->save() 时尝试什么,它都不会让我绕过这个属性不在表上。 (2认同)

pwy*_*wyg 6

我知道这个问题很老了,但它在最近的搜索结果中名列前茅,我试图解决类似的问题,我认为这可能是 Laravel 访问器/变异器的理想情况。我已经在 Laravel 5.6 上对此进行了测试,但相信它最早可以在 4.2 上运行。

通过创建一个修改器和访问器而不是公共属性,它将允许将该字段添加为可填充以进行批量分配,同时仍将其从内部属性中排除(从而防止其错误地保存到数据库)。我了解最初的请求排除了批量分配,但这并不一定排除这个答案。我认为一个例子会有所帮助:

class Foo extends Model
{
    //Allow bar in mass assignment
    protected $fillable = [
            "bar"
        ];

    /**
     * Store bar in protected variable instead of attributes
     * Because bar is not set in attributes, Laravel will not try to save it to database
     */
    protected $bar;

    /**
     * Mutator method to set bar's value
     */
    public function setBarAttribute($value)
    {
        $this->bar = $value;
    }

    /**
     * Accessor method to retrieve bar's value
     */ 
    public function getBarAttribute()
    {
        return $this->bar;
    }
}
Run Code Online (Sandbox Code Playgroud)

当使用质量分配创建此模型时,如果质量分配值中存在 bar,则将为 bar 调用 mutator (setBarAttribute) 方法。每当访问 bar 属性时,都会调用相应的 get/set 方法。因为变异器没有在模型的内部属性变量中设置 bar 的值,所以模型不会将 bar 保存到数据库中。


Lan*_*och -1

添加 $fillable ,模型将忽略其中不存在的所有内容(而不是给出错误)。使用构造函数填充所有列是可选的。

class Foo extends Model
{
    protected $fillable = ['id', 'description', 'user_id'];
}

$f = new Foo(['id' => 1, 'description' => "hello monkey", 'user_id' => 55, 'bar' => 'wow']); // should work w/o error, but it ignores the 'bar'.
Run Code Online (Sandbox Code Playgroud)

  • 看起来使用 `$fillable` 不仅可以阻止任何将该值保存到数据库的尝试,而且还可以防止该属性首先被设置。换句话说,它不太有效,因为我需要将该属性传递给另一个类,但只是不保存。 (5认同)