Diferenças entre algum?"e" existe? em Ruby on Rails?
ou seja, eles são ActiveRecord::FinderMethods' existe? e a relação é alguma?. Executando-os numa consulta genérica (Foo.first.bars.exists?
e Foo.first.bars.any?
) gerou SQL equivalente. Há alguma razão para usar um em vez do outro?
2 answers
#any
e #exists?
são animais muito diferentes, mas questionam da mesma forma.
Principalmente, #any?
aceita um bloco - e com este bloco recupera os registos na relação, chama #to_a
, chama o bloco, e depois atinge-o com Enumerable#any?
. Sem um bloco, é o equivalente a !empty?
e conta os registos da relação.
#exists?
Sempre questiona a base de dados e nunca se baseia em registos pré-carregados, e define um limite de 1. É muito mais performant vs #any?
. #exists?
também aceita uma opção param como condições para aplicar como você pode ver nos documentos.
A utilização de ActiveRecord#any?
é reduzida ao longo de ActiveRecord#exists?
. Com algum? você pode verificar, no caso de passar um bloco, se certos elementos desse array correspondem aos critérios. Semelhante à Enumerable#any?
mas não os confunda.
O ActiveRecord#any?
implementa a Enumerable#any?
dentro da lógica da sua definição , convertendo a relação acedida a um array no caso de um bloco ter sido passado para ele e produz e acede aos parâmetros do bloco para implementar de uma forma "manual " um" Ruby " any?
metodo.
O outro útil adicionado pretende devolver a negação do vazio? aplicado à relação. É por isso que se pode verificar de ambos os modos se um modelo tem ou não registos, como:
User.count # 0
User.any? # false
# SELECT 1 AS one FROM "users" LIMIT ? [["LIMIT", 1]]
User.exists? # false
# SELECT 1 AS one FROM "users" LIMIT ? [["LIMIT", 1]]
Você também pode verificar No " qualquer?"way, if some record attribute has a specific value:
Foo.any? { |foo| foo.title == 'foo' } # SELECT "posts".* FROM "posts"
Ou salvar a "eficiência" usando existe? e melhore sua consulta e linhas de código:
Foo.exists?('foo') # SELECT 1 AS one FROM "posts" WHERE "posts"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
ActiveRecord#exists?
oferece muitas implementações e se destina a trabalhar em um nível SQL, ao invés de any?
, isso de qualquer maneira irá converter a relação com que você está trabalhando em um array se você não passar um bloco.