skip to Main Content

I am using Laravel 7.30.6 and have PHP 8.0.10 on my development machine; I am experiecing a weird issue where any model attributes that are booleans in my DB and have been correctly added to my $casts attribute in the Model still return 1 if the DB value is true.

I did see this SO post where they mentioned this is a bug, but it appears its been resolved in PHP8.0.6 which I’m already using a version higher than.

Can someone tell me how to resolve this? I have confirmed I am using PHP8.0.10 by typing php -v into my terminal.

Edit:
I have updated to Laravel v8.80 and this is still encountering the same issues. My PHP version is v8.0.10 which is beyond the v8.0.6 version claimed in the github issue page to have fixed it yet the problem still exists for me.

Second Edit:
Table Defintion using PostgreSQL v12.2

| table_name | column_name              | data_type                   |
|------------|--------------------------|-----------------------------|
| businesses | id                       | bigint                      |
| businesses | name                     | text                        |
| businesses | business_type_id         | bigint                      |
| businesses | is_active                | boolean                     |
| businesses | created_at               | timestamp without time zone |
| businesses | updated_at               | timestamp without time zone |
| businesses | enable_multi_queue       | boolean                     |
| businesses | multi_queue_active       | boolean                     |
| businesses | enable_shortest_option   | boolean                     |
| businesses | default_shortest         | boolean                     |

Model defintion:

class Business extends Model
{
    protected $casts = [
        'is_active'                 => 'boolean',
        'enable_multi_queue'        => 'boolean',
        'multi_queue_active'        => 'boolean',
        'enable_shortest_option'    => 'boolean',
        'default_shortest'          => 'boolean',
    ];

Link to Github Issue:
https://github.com/laravel/framework/issues/37215

3

Answers


  1. Chosen as BEST ANSWER

    The answer to my issue raised for anyone experiencing the same issue:

    Laravel by default when storing booleans (in Postgress) will return those values in boolean values when used in any logic and if you return your model in JSON. If you however try to print those boolean attributes in a Blade template, it will display either 1 or white space, it was this that was confusing me as the JSON output and the blade output were different.

    I fixed this by pretending my blade output with json_encode($attribute), you could do this in a smarter way by using getters of course.


  2. I don’t know how PostgreSQL would actually store & return data-type boolean,

    but Attribute Casting literally states, that:

    … which is stored in our database as an integer (0 or 1) to a boolean value.

    Therefore, change columns enable_multi_queue
    multi_queue_active
    enable_shortest_option
    default_shortest to the shortest integer type available, like INT or TINYINT, values 0 / 1.
    The model may well return bool, if only the expected input type is suitable.

    Login or Signup to reply.
  3. I would recommend that you set the data type to TINYINT(1). TINYINT(1) is basically a Boolean. 1 means TRUE and 0 FALSE. MySQL, MariaDB, sqlite doesn’t have a real Boolean type either. In MySQL, Boolean is just a synonym for a TINYINT(1).

    If you have changed to TINYINT ($table->tinyInteger();), Laravel will do the cast correctly.

    protected $casts = [
        'is_active' => 'boolean',
    ];
    

    This means you have a value of type boolean and you are able to do strict (===) comparisons in your code. Like $business->is_active === TRUE ? 'is_true' : 'is_false';

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search