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

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

public $quantity = 9;

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

那我该怎么办?

【问题讨论】:

    标签: php model laravel laravel-4 eloquent


    【解决方案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");
                });
            }
        
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-11-12
          • 2016-02-20
          • 2017-02-16
          • 2014-08-17
          • 1970-01-01
          • 1970-01-01
          • 2014-12-05
          • 1970-01-01
          相关资源
          最近更新 更多