3

I'm set all empty fields to null when saving

Using OctoberCMS model event beforeSave (equivalent to Laravel model saving)

public function beforeSave()
{
    // $this => the model
    foreach ( $this->toArray() as $name => $value )
    {
         if ( empty( $value ) ) {
                 $this->{$name} = null;
         }
    }
}

The problem is when field has a default value defined on database (mysql), for example:

$table->integer('value')->default(1);

I need to get an array of all nullable or not nullable fields of current model.

How do this?

0

3 Answers 3

6

Laravel/Eloquent have no clue about the structure of your database. Assumption is made that whatever operations you implement, database structure is ready for them.

You could query the database to get information about columns. For MySQL you'd need to run

show columns from <table_name>;

This will result in additional queries sent to the database.

A better option, in my opinion, is to just store such information in model classes, e.g. in

protected $notNullable = ['field1', 'field2'];

in a similar fashion like $fillable or $guarded fields are stored. When you write your models you should be aware which columns are nullable and which aren't, so it should be the easiest solution.

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

2 Comments

Dear down-voters, please leave a comment, I'd love to learn what is wrong with the answer :)
oh sorry. to solve i just set protected $notNullables = ['foo', 'bar'] and create the conditions inside the loop. Worked fine.
2

Add this to your model or trait

use DB;
...
    protected static $_columns_info = NULL;
    protected static $_nullable_fields = NULL;
    public function is_nullable(string $field_name){
        if (is_null(static::$_columns_info) ){
            static::$_columns_info = DB::select('show columns from '.$this->gettable() );
        }
        if (is_null(static::$_nullable_fields) ){
            static::$_nullable_fields = array_map( function ($fld){return $fld->Field;}, array_filter(static::$_columns_info,function($v){return $v->Null=='YES';}));
        }
        return in_array( $field_name, static::$_nullable_fields );
    }

and use like

app(Model::class)->is_nullable(you_column_name)

Comments

0

For PostgreSQL I've updated Sole.dmitry's answer and made a funcion, wich can be performed on a given model. For ex. model User, then on an instance $user->getNullableFields() will return them as an array of the field names that are nullable

public function getNullableFields(){

        $columns_info = DB::select("SELECT COLUMN_NAME, IS_NULLABLE FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = '{$this->getTable()}'");

        $nullableFields = array_filter($columns_info, function($v) { return $v->is_nullable == 'YES'; });

        $nullable_fields = json_decode(json_encode($nullableFields), true);

        return array_map(function ($fields) { return $fields['column_name']; }, $nullable_fields);
    }

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.