Reputation: 2845
Lets say we have the following struct:
type Task struct {
...
Completed bool `gorm:"default:false" json:"-"`
}
There are 5 entries in the MySQL DB:
Completed=1
Completed=0
I face the following peculiarity:
db, err = gorm.Open("mysql", connstr)
var ret []Task
// This returns 3 rows
db.Debug().Model(&Task{}).Find(&ret, "Completed =?", false)
// This returns 2 rows
db.Debug().Model(&Task{}).Find(&ret, Task{Completed: true})
// BUT THIS RETURNS 5 ROWS!
db.Debug().Model(&Task{}).Find(&ret, Task{Completed: false})
Any ideas why is this happening? The SQL executed at the last call was:
SELECT * FROM 'tasks'
I would like to avoid writing a new SQL query for each struct field. Passing the struct (object) seems more sensible.
Upvotes: 2
Views: 1404
Reputation: 2245
GORM looks at the fields of the struct provided to Find()
, and checks to see which fields are set, to construct the query. So in the 2nd example, it sees that Completed
is set to true
, and adds a WHERE clause to the query:
db.Debug().Model(&Task{}).Find(&ret, Task{Completed: true})
generates:
SELECT * FROM "tasks" WHERE "tasks"."completed" = true
In the second example, GORM has no way of knowing if you passed in Task{Completed: false}
or simply Task{}
because false
is the zero-value of a bool
.
The same thing would happen if you had a field that was an int
and tried to query for 0
:
db.Debug().Model(&Task{}).Find(&ret, Task{Num: 0}) // Generates: SELECT * FROM 'tasks'
If you really want to use the struct for queries, you can change your model so that Completed
is a *bool
instead of a bool
. Since the zero-value of a pointer is nil, providing a pointer to false will tell GORM to add that clause:
trueBool := true
falseBool := false
db.Debug().Model(&Task{}).Find(&ret, Task{Completed: &falseBool})
db.Debug().Model(&Task{}).Find(&ret, Task{Completed: &trueBool})
generate (respectively)
SELECT * FROM "tasks" WHERE "tasks"."completed" = false
SELECT * FROM "tasks" WHERE "tasks"."completed" = true
Just remember that doing this means that Completed
can be saved in the DB as NULL
if not set.
Upvotes: 3