如何为 Laravel / Eloquent 模型设置默认属性值?

Posted

技术标签:

【中文标题】如何为 Laravel / Eloquent 模型设置默认属性值?【英文标题】:How to set a default attribute value for a Laravel / Eloquent model? 【发布时间】:2013-09-15 20:24:18 【问题描述】:

如果我尝试声明一个属性,像这样:

public $quantity = 9;

...它不起作用,因为它不被视为“属性”,而仅仅是模型类的属性。不仅如此,我还阻止了对实际存在的“数量”属性的访问。

那我该怎么办?

【问题讨论】:

【参考方案1】:

对此的更新...

@j-bruni 提交了一个提案,Laravel 4.0.x 现在支持使用以下内容:

protected $attributes = array(
  'subject' => 'A Post'
);

它会在你构造时自动将你的属性subject 设置为A Post。您不需要使用他在回答中提到的自定义构造函数。

但是,如果您最终使用了像他一样的构造函数(我需要这样做才能使用Carbon::now()),请注意$this->setRawAttributes() 将覆盖您使用上面的$attributes 数组设置的任何内容。例如:

protected $attributes = array(
  'subject' => 'A Post'
);

public function __construct(array $attributes = array())

    $this->setRawAttributes(array(
      'end_date' => Carbon::now()->addDays(10)
    ), true);
    parent::__construct($attributes);


// Values after calling `new ModelName`

$model->subject; // null
$model->end_date; // Carbon date object

// To fix, be sure to `array_merge` previous values
public function __construct(array $attributes = array())

    $this->setRawAttributes(array_merge($this->attributes, array(
      'end_date' => Carbon::now()->addDays(10)
    )), true);
    parent::__construct($attributes);

请参阅Github thread 了解更多信息。

【讨论】:

非常感谢您的帮助 您知道如何使值随机生成,而不是每次模型实例化时都相同吗? (这可能值得一个单独的问题,但我想先发表评论) @PetarVasilev 您可以使用上面的__construct 覆盖方式,并在分配时调用一个生成随机值的函数。 我这样做了,但是当创建用户时,除了我的随机值之外,没有数据保存在数据库中 @PetarVasilev 听起来这可能是一个批量分配问题,但最好为它打开一个新主题。【参考方案2】:

这就是我现在正在做的事情:

protected $defaults = array(
   'quantity' => 9,
);

public function __construct(array $attributes = array())

    $this->setRawAttributes($this->defaults, true);
    parent::__construct($attributes);

我建议将此作为 PR,因此我们不需要在每个模型中声明此构造函数,并且可以通过在模型中简单地声明 $defaults 数组来轻松应用...


更新

正如 cmfolio 所指出的,实际的答案非常简单

只需覆盖$attributes 属性!像这样:

protected $attributes = array(
   'quantity' => 9,
);

该问题已在here 进行了讨论。

【讨论】:

J.Bruni,介意分享公关网址吗?所以我们也可以跟踪它:) @TianLoon,我已经更新了答案。原始 PR 在这里:github.com/laravel/framework/pull/2264 - 在了解了更多关于 $attributes 并承认没有必要之后,我自己关闭了它。有关详细信息,请参阅@cmfolio 答案(他正在使用我提出的解决方案,因为他需要为一个默认值实例化一个对象)。 @J.Bruni 你好,我尝试覆盖 $attributes 就像你的答案一样。当dd() 默认属性值正确显示时。但是 mutators 属性不适用于这种方式。 :/ 我在 laravel 5 中这样做【参考方案3】:

我知道这真的很老了,但我刚刚遇到了这个问题,并且能够使用 this site 解决这个问题。

将此代码添加到您的模型中

protected static function boot()

   parent::boot();

   static::creating(function ($model) 
        $model->user_id = auth()->id();
    );

更新/免责声明

此代码有效,但它会覆盖常规 Eloquent 模型 creating 事件

【讨论】:

【参考方案4】:

通过构造设置属性值

  public function __construct()
    
        $this->attributes['locale'] = App::currentLocale();
    

【讨论】:

【参考方案5】:

我将它用于 Laravel 8(静态和动态更改属性)

<?php

namespace App\Models\Api;

use Illuminate\Database\Eloquent\Model;

class Message extends Model

    /**
     * Indicates if the model should be timestamped.
     *
     * @var bool
     */
    public $timestamps = false;


    protected static function defAttr($messages, $attribute)

        if(isset($messages[$attribute]))
            return $messages[$attribute];
        

        $attributes = [ 
            "password" => "123",
            "created_at" => gmdate("Y-m-d H:i:s"),
        ];

        return $attributes[$attribute];
    
    

    /**
     * The "booted" method of the model.
     *
     * @return void
     */
    protected static function booted()
    
        static::creating(function ($messages) 
            $messages->password = self::defAttr($messages, "password");
            $messages->created_at = self::defAttr($messages, "created_at");
        );
    


【讨论】:

以上是关于如何为 Laravel / Eloquent 模型设置默认属性值?的主要内容,如果未能解决你的问题,请参考以下文章

Payum - Laravel 4 的包。如何使用 Eloquent 而不是 FilesystemStorage 创建模型数据?

我应该如何为需要引用数据透视表的表配置 Laravel / OctoberCMS 模型?

深入理解 Laravel Eloquent——模型间关系(关联)

Laravel Eloquent ORM 数据model操作

Laravel Eloquent模型单元测试

Laravel Eloquent 模型单元测试