Carlos Brando

Nome do Jogo

Deixando meus métodos de pesquisa mais espertos

1858685882_35f2f01bca.jpg

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.

Comments