yii2-openapi icon indicating copy to clipboard operation
yii2-openapi copied to clipboard

Bool field with default value and not in required section generate null() in migration files

Open SOHELAHMED7 opened this issue 4 years ago • 4 comments

For field with bool data type which have default value either true or false, and not in required section,

its migration is generated as

$this->boolean()->null()->defaultValue(false)

Ideally it should be

$this->boolean()->defaultValue(false) (or true as default value) no matter it is in required section or nor

Feel free to let me know if more info is needed.

SOHELAHMED7 avatar Jun 29 '21 11:06 SOHELAHMED7

What is wrong? We generate all properties explicitly, even if they are default.

Insolita avatar Jun 29 '21 12:06 Insolita

If a property is of type boolean and has default value then this should not be generated in migration file:

$this->boolean()->null()->defaultValue(false)

Here null() is present however ideally it should be there.

In correct scenario IMHO it should be

$this->boolean()->defaultValue(false)

SOHELAHMED7 avatar Jun 29 '21 13:06 SOHELAHMED7

But boolean fields may be stored with allowing null as well as without, even when default value declared, it depends on a case. Some of them may require indeterminate state

Insolita avatar Jun 29 '21 15:06 Insolita

Null/Not null state depends on the "required" property in your model schema definition.

title: MyTable
x-table: my_table
type:object
required:
   - id
   - name
   - is_active

properties:
    id:
        type: integer
        readOnly: true
   name: 
       type: string
   is_active:
       type: boolean
       default: false
   is_confirmed:
       type: boolean
       default: false

will generate for is_active $this->boolean()->notNull()->defaultValue(false) and for is_confirmed $this->boolean()->null()->defaultValue(false)

When table migration will be applied and you change the schema like

title: MyTable
x-table: my_table
type:object
required:
   - id
   - name
   - is_confirmed

properties:
    id:
        type: integer
        readOnly: true
   name: 
       type: string
   is_active:
       type: boolean
       default: false
   is_confirmed:
       type: boolean
       default: false

You will receive change migration like this (for postgres)

    public function safeUp()
    {
        $this->alterColumn('{{%my_table}}', 'is_active', 'DROP NOT NULL');
        $this->alterColumn('{{%my_table}}', 'is_confirmed', 'SET NOT NULL');
    }

    public function safeDown()
    {
        $this->alterColumn('{{%my_table}}', 'is_confirmed', 'DROP NOT NULL'));
        $this->alterColumn('{{%my_table}}', 'is_active',  'SET NOT NULL');
    }

And your changes will be clear

Insolita avatar Jun 29 '21 16:06 Insolita