ActiveRecord 中的一个小陷阱

我们在 ActiveRecord 中使用where查询时,通常是下面这样写

User.where("name = ?", name)

在查询中我们使用?来为我们转义,这样有效的避免了SQL injection。今天发现在有有一种情况下需要我们特别的注意,那就是当查询条件为nil的时候。根据条件我们希望生成的SQL语句是这样SELECT * FROM users WHERE users.name IS NULL

按照之前的查询,我们通常的查询是

User.where("name = ?", nil)
# => User Load (1.8ms)  SELECT "users".* FROM "users" WHERE (email = NULL)

可以看到生成的查询语句并不是我们所要的,原因就是Rails 没有那么聪明,这里?并不知道我们需要把email = NULL转换为email IS NULL

所以在nil的情况下我们改用这种方式查询

User.where(name: nil)
# => User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."name" IS NULL

可以看到,后者的速度相比前者有很大的提升。