Negação em queries usando where.not

Dicas - 13/Jul/2020 - por André Kanamura

Desde a versão 4.0 do Rails temos disponível no Active Record o método: where.not. Com ele é possível simplificar algumas queries. Vamos usar como exemplo uma aplicação onde temos carros para locação e, para isso, registramos Fabricantes pelo model Manufacturer. Se rodarmos no console:

$ Manufacturer.all

Manufacturer Load (0.3ms)  SELECT  "manufacturers".* FROM "manufacturers" LIMIT ?  [["LIMIT", 11]]
=> #<ActiveRecord::Relation 
[#<Manufacturer id: 1, name: "Fiat", created_at: "2020-07-09 17:47:13", updated_at: "2020-07-09 17:47:13">, 
#<Manufacturer id: 2, name: "Ford", created_at: "2020-07-09 17:47:13", updated_at: "2020-07-09 17:47:13">, 
#<Manufacturer id: 3, name: "Toyota", created_at: "2020-07-09 17:47:13", updated_at: "2020-07-09 17:47:13">]>

Para realizarmos uma query que retorna os fabricantes com nomes diferentes de "Fiat" poderíamos rodar:

$ Manufacturer.where("name != ?", "Fiat")

Manufacturer Load (0.6ms)  SELECT  "manufacturers".* FROM "manufacturers" WHERE (name != 'Fiat') LIMIT ?  [["LIMIT", 11]]
=> #<ActiveRecord::Relation 
[#<Manufacturer id: 2, name: "Ford", created_at: "2020-07-09 17:47:13", updated_at: "2020-07-09 17:47:13">, 
#<Manufacturer id: 3, name: "Toyota", created_at: "2020-07-09 17:47:13", updated_at: "2020-07-09 17:47:13">]>

E este seria o mesmo resultado se usássemos:

$ Manufacturer.where.not(name: "Fiat")

Manufacturer Load (0.8ms)  SELECT  "manufacturers".* FROM "manufacturers" WHERE "manufacturers"."name" != ? LIMIT ?  [["name", "Fiat"], ["LIMIT", 11]]
=> #<ActiveRecord::Relation 
[#<Manufacturer id: 2, name: "Ford", created_at: "2020-07-09 17:47:13", updated_at: "2020-07-09 17:47:13">, 
#<Manufacturer id: 3, name: "Toyota", created_at: "2020-07-09 17:47:13", updated_at: "2020-07-09 17:47:13">]>

As queries executadas no banco são ligeiramente diferentes, mas os resultados obtidos são os mesmos. A principal diferença é que o where.not permite ao Rails aproveitar mais recursos de Prepared Statements, mas isso é assunto para outro texto =)

Referências

Foto de perfil do autor
André Kanamura

Dev na Campus Code