
Imagine o seguinte método:
def count_users(type) User.count(:all, :conditions => ["type = ?", type]) end
É um método simples, que irá me retornar a quantidade de usuários de um determinado tipo. Agora, vamos testar nosso método (preste atenção aos comandos SQL gerados):
>> count_users(1) => 2 SELECT count(*) AS count_all FROM users WHERE (type = 1) >> count_users(2) => 5 SELECT count(*) AS count_all FROM users WHERE (type = 2)
Ok, até aqui tudo funciona perfeitamente, mas e se eu desejasse contar todos os usuários que tivessem a coluna type com o valor NULL?
>> count_users(nil) => 0 SELECT count(*) AS count_all FROM users WHERE (type = NULL)
Opa, eu tenho um registro no meu banco com o valor NULL, mas o meu método retornou zero. O que saiu errado? Note a query gerado pelo comando, type = NULL está errado, deveríamos usar type IS NULL.
Preciso alterar meu método:
def count_users(type)
User.count(:all, :conditions => {:type => type})
end
Note que alterei a forma como o parâmetro :conditions estava sendo usado. Neste caso especifico, meu método ficou muito mais robusto. Veja alguns exemplos:
>> count_users(1) => 2 SELECT count(*) AS count_all FROM users WHERE (users."type" = 1) >> count_users(2) => 5 SELECT count(*) AS count_all FROM users WHERE (users."type" = 2) >> count_users(nil) => 1 SELECT count(*) AS count_all FROM users WHERE (users."type" IS NULL) >> count_users([1,3]) => 3 SELECT count(*) AS count_all FROM users WHERE (users."type" IN (1,3)) >> count_users(1..3) => 8 SELECT count(*) AS count_all FROM users WHERE (users."type" BETWEEN 1 AND 3)
Note que agora, mesmo passando nil ou um array para o método, ele criará a query de pesquisa da forma correta de acordo com o tipo do objeto usado.