Suppose I have Post
model that has is_verified
column with smallint
datatype, how can I get all records that is verified? One thing to do this is using this:
Post::where('is_verified', true)->get();
The code above will produce the following query:
select * from `posts` where `posts`.`is_verified` = true
… which will get me all verified Post
records; in note that is_verified
on all existing records is either 0
or 1
.
However, after I get myself curious and try to manually change some is_verified
‘s record value from 1
to another truthy number e.g. 2
, the above eloquent query didn’t work as expected anymore: records with is_verified
value of 2
didn’t get retrieved.
I tried to execute the sql query directly from HeidiSQL as well, but it was just the same. Then I tried to change the =
in the sql query to is
, and now it’s working as expected i.e. all records with truthy is_verified
get retrieved:
select * from `posts` where `posts`.`is_verified` is true
So my questions are:
- Does the above behaviour is correct and expected?
- How can I execute the last sql query in eloquent? One thing I can think of is
where('is_verified', '!=', 0)
but that feels weird in terms of readability especially when the query is pretty long and a bit complicated - As I stated before, the
is_verified
column is asmallint
. Does this affects the behaviour? Because this conversation here states thatboolean
column datatype is typicallytinyint
, notsmallint
.
And that’s it. Thank you in advance!
2
Answers
After doing some deeper digging, I would like to write down the things I've found:
I have updated my mysql to the newest version as of now (v8) and
boolean
datatype defined in migration results intinyint(1)
in the db. This is happening turns out because in mysqlbool
orboolean
are actually just the synonyms oftinyint(1)
, so that was a totally normal behaviour, not due to lower-version issues.I found @dz0nika answer that states that
smallint
andtinyint
results in different behaviour in the query to be quite incorrect. The two datatypes simply differ in terms of byte-size while storing integer value.As of mysql documentation, it is stated that:
But also that:
Meaning that:
Is the same as
Thus the query will only get
Post
records withis_verified
value of1
.To get
Post
records with truthyis_verified
value, wether1
, or2
, or3
, etc; useis
instead of=
in the query:You can read more about these informations here and here (look for the "boolean" part)
So, how about the eloquent query? How can we get
Post
with truthyis_verified
using eloquent?I still don't know what's best. But instead of using
where('is_verified', '!=', 0)
as I stated in my question, I believe it's better to usewhereRaw()
instead:If you found this information to be quite missing or incorrect, please kindly reply. Your opinion is much appreciated.
smallint
, you can use the explicit boolean column type as described in the documentation.Post::where('is_verified', true)->get();
will return the expected results.smallint
column type, if you puttinyint
it also should work like the boolean column. You can read more about the differences here.