LARAVEL how to change $fillable in Model from trait?

laravel initialize trait
fillable laravel
laravel model traits
laravel traits
laravel findorcreate
firstorcreate in laravel
laravel cursor
laravel where

I have in model:

use seoTrait;

protected $fillable = [
    'name', 'title', 'description'
];

I created trait "seoTrait" which need "seoMeta" in $fillable.

Now I add :

protected $fillable = [
    'name', 'title', 'description', 'seoMeta'
];

But is it possible in trait "seoTrait" add something to $fillable ?


You should be able to use the boot method of Traits like so

public static function bootSeoTrait()
{
    $this->fillable[] = 'seoMeta';
}

This way whenever your model boots up, this method of your Trait will be called ans 'seoMeta' should be added to $fillable

EDIT

This answer will not work since bootSeoTrait is a static method, $this will not be available.

See @DokiCRO answer here

Since this answer is accepted, I can't delete it.

EDIT 2

Laravel now supports the initialize* method to initialize model traits. See @OneBigOwnage answer here

Here's how you could use a trait to update the fillable property on , <?php. namespace App\Traits;. trait Auditable. {. /**. * The fillable properties for this trait which will be applied to the model. *. * @var array. */. protected  Laravel Fillable Relations. This library provides a trait for mixing in to an Eloquent Model. Doing so will enable support for fillable relations. To use, first require in your composer file: composer require troelskn/laravel-fillable-relations Then, in your code:


For anyone that came here looking for an answer; I believe that there is a better way than constructor overloading.

Others have pointed out that Laravel supports bootable model traits, using the boot<TraitName> method you can set up the trait for usage. However, the boot<TraitName> method has to be static, so you cannot alter any non-static properties of the model.

However, I found out that there is a non-static equivalent to the boot<TraitName> method; the initialize<TraitName> method.

Internally, when Eloquent boots up a model, it also registers all initialize methods for the model, based on the methods found in the traits that the model uses. Then upon instantiating that model, the initialize methods are fired.

An example of usage, based on the problem stated in this question:

trait SEOTrait
{
    /**
     * This method is called upon instantiation of the Eloquent Model.
     * It adds the "seoMeta" field to the "$fillable" array of the model.
     *
     * @return void
     */
    public function initializeSEOTrait()
    {
        $this->fillable[] = 'seoMeta';
    }
}

Sadly there isn't any information in the official documentation about either bootable or initializable traits. However, I still find it really cool that both functionalities exist.

Define model attributes in trait?, The logical way seemed to press the $appends and the two added functions into a trait, but when I do that and command the model to use that  A “Trait” is similar to an abstract class, in that it cannot be instantiated on its own but contains methods that can be used in a concrete class. Traits were introduced in PHP in version 5.4 and are used extensively in the Laravel Framework.


I had the same requirement. However, I didn't want to declare a constructor in my trait, as this leads to very unexpected behaviour - what if another trait also declares a constructor?

As pointed out by PeterPan666, we can't use the static trait boot() method to directly set the non-static fillable property - but we can utilise Laravel Model Events, which receive an instance of the model.

For example:

public static function bootSeoTrait() : void
{
    static::retrieved(function($model) {
        $model->fillable = array_merge($model->fillable, ['seoMeta']);
    });
}

Update

Although the $fillable property is protected, the GuardsAttributes trait - which the Illuminate\Database\Eloquent\Model uses - contains the following setter:

/**
 * Set the fillable attributes for the model.
 *
 * @param  array  $fillable
 * @return $this
 */
public function fillable(array $fillable)
{
    $this->fillable = $fillable;

    return $this;
}

So, we can set the $fillable protected property from our model instance in the retrieved event.

Mass assignment in Eloquent models. Diffrent input and model field , Is it any possibility to match Request's inputs with model's fields? PHP does not like variables with dashes so using them causes this If you cannot / will not change the form then explicitly pass the fields to the model as a new array; updateFromInput(array $input) { $fillable = $this->getFillable(); $map  The package can automatically log events such as when a model is created, updated and deleted. To make this work all you need to do is let your model use the Spatie\Activitylog\Traits\LogsActivity -trait. As a bonus the package will also log the changed attributes for all these events when setting $logAttributes property on the model.


You can use constructor inside your trait, but it is important to send fillable attributes to parent constructor Illuminate\Database\Eloquent\Modal

    parent::__construct($attributes);

Here is example code:

public function __construct(array $attributes = []) {
    parent::__construct($attributes);
    $this->fillable[] = 'seoMeta';
}

Eloquent: Getting Started - Laravel, Models allow you to query for data in your tables, as well as insert new records into All Eloquent models extend Illuminate\Database\Eloquent\Model class. you will need to specify either a fillable or guarded attribute on the model, as all  The Eloquent ORM included with Laravel provides a beautiful, simple ActiveRecord implementation for working with your database. Each database table has a corresponding "Model" which is used to interact with that table. Before getting started, be sure to configure a database connection in config/database.php. To get started, create an Eloquent


As @DokiCRO said, you could implement a constructor within your trait. You must then consider that there won't be any other trait that will be able to overwrite the construct.

For anything else, I would suggest to go with the static bootTraitClassName(). But in this specific case we need to overwrite a non-static protected property, which can't be achievable within a static context.

So this justifies the constructor overload. Maybe use one trait that is responsible for overloading $fillable arrays for all your models, which will make your life easier in the long run.

Just make sure to include your code before the parent construct gets called though.

public function __construct(array $attributes = []) {
    $this->fillable[] = 'seoMeta';

    parent::__construct($attributes);
}

Eloquent ORM - Laravel, To get started, set the fillable or guarded properties on your model. To update a model, you may retrieve it, change an attribute, and use the save method: use Illuminate\Database\Eloquent\SoftDeletingTrait; class User extends Eloquent  Forum Laravel Problem with Trait and fillable. Reply Follow All Threads I used a trait inside a model but when i using create function in controller,


LARAVEL how to change $fillable in Model from trait?, I have in model: use seoTrait; protected $fillable = [ 'name', 'title', 'description' ]; I created trait "seoTrait" which need "seoMeta" in $fillable. Now I add : protected  Laravel-Uploadable. Laravel Uploadable trait to automatically upload images and files with minimum configuration. Introduction. This package can help you to easily make uploads, using only one field in the database, and some simple attributes in your model class.


20 Laravel Eloquent Tips and Tricks, There is a magical place called boot() in an Eloquent model where you can is setting some field value at the moment of creating the model object. class User extends Model { protected $table = 'users'; protected $fillable out the code of default abstract Model class and check out all the traits used. Accessors and mutators allow you to format Eloquent attribute values when you retrieve or set them on model instances. For example, you may want to use the Laravel encrypter to encrypt a value while it is stored in the database, and then automatically decrypt the attribute when you access it on an Eloquent model.


Tips, Tricks, and Good Practices with Laravel's Eloquent, The Eloquent ORM included with Laravel provides a beautiful, simple ActiveRecord implementation for Note: $fillable / $guarded properties class Post extends Model { use HasUuid; } trait HasUuid { public static function  Hi @troelskn I agree that a trait is an excellent solution to this issue, especially given that Eloquent models now use traits for most functionality. Also having this as a separate package would help to see if there is a need for this in the Laravel core and to work out the complexities first.