59

If I try declaring a property, like this:

public $quantity = 9;

...it doesn't work, because it is not considered an "attribute", but merely a property of the model class. Not only this, but also I am blocking access to the actually real and existent "quantity" attribute.

What should I do, then?

5 Answers 5

94

An update to this...

@j-bruni submitted a proposal and Laravel 4.0.x is now supporting using the following:

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

Which will automatically set your attribute subject to A Post when you construct. You do not need to use the custom constructor he has mentioned in his answer.

However, if you do end up using the constructor like he has (which I needed to do in order to use Carbon::now()) be careful that $this->setRawAttributes() will override whatever you have set using the $attributes array above. For example:

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);
}

See the Github thread for more info.

Sign up to request clarification or add additional context in comments.

6 Comments

Do you know how to make the value randomly generated rather than being the same every time the models gets instantiated? (this might be worth a separate question but I thought to comment first)
@PetarVasilev You can use the __construct override way above and call a function that generates your random value when assigning it.
I did that but when the user was created no data was saved in the database apart from my random value
@PetarVasilev Sounds like it might be a mass assignment issue, but probably best to open a new topic for it.
@cmfolio I made a separate question for it, here it is: stackoverflow.com/questions/33651063/…
|
59

This is what I'm doing now:

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

public function __construct(array $attributes = array())
{
    $this->setRawAttributes($this->defaults, true);
    parent::__construct($attributes);
}

I will suggest this as a PR so we don't need to declare this constructor at every Model, and can easily apply by simply declaring the $defaults array in our models...


UPDATE:

As pointed by cmfolio, the actual ANSWER is quite simple:

Just override the $attributes property! Like this:

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

The issue was discussed here.

4 Comments

J.Bruni, mind sharing the PR url? so we can keep track of it also :)
@TianLoon, I've updated the answer. The original PR is here: github.com/laravel/framework/pull/2264 - I closed it myself after learning more about $attributes and acknowledging it was not necessary. See @cmfolio answer for details (he is using my proposed solution, because he needs to instantiate an object for one default).
@J.Bruni hello, I was try by overrid the $attributes like your answer. when dd() the default attributes value show correctly. but the mutators attribute not work for this way. :/ i do this in laravel 5
I was trying this, but initial value is vanished when using A::where(...)->first(). Only works when using new A(). x.x
8

I know this is really old, but I just had this issue and was able to resolve this using this site.

Add this code to your model

protected static function boot()
{
   parent::boot();

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

Update/Disclaimer

This code works, but it will override the regular Eloquent Model creating Event

Comments

1

I use this for Laravel 8 (static and to dynamically change attributes)

<?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");
        });
    }

}

1 Comment

What about inserting ? this function is not working for insert function.
1

Set the attribute value in the constructor:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.