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
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.I don’t know how PostgreSQL would actually store & return data-type
boolean
,but Attribute Casting literally states, that:
Therefore, change columns
enable_multi_queue
multi_queue_active
enable_shortest_option
default_shortest
to the shortestinteger
type available, likeINT
orTINYINT
, values0
/1
.The model may well return
bool
, if only the expected input type is suitable.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.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';