As consultas do ActiveRecord e você: como encontrar () o método certo para o trabalho

Foto de Agence Olloweb em Unsplash

Se você é como eu, sua experiência ao aprender sobre bancos de dados como novo programador foi uma experiência inspiradora. De repente, o complexo funcionamento interno da Internet ficou claro diante de você - são tabelas e associações por todo o caminho.

Se você também é como eu quando se trata de aprender SQL e como realmente interagir com esses bancos de dados, suas primeiras experiências foram provavelmente um pouco rudes de despertar do seu devaneio induzido anteriormente. De repente, você percebe que, para cada banco de dados que armazena grandes quantidades de informações, deve haver alguém que saiba como lidar com a maldita coisa para obter essas informações. E você provavelmente percebeu que alguém em particular, mais cedo ou mais tarde, será você.

Felizmente, as estruturas de programação modernas nos deram maneiras convenientes e intuitivas de criar, armazenar e recuperar dados. Hoje, falaremos sobre uma estrutura específica - Ruby on Rails - e um aspecto específico que torna a gestão de banco de dados uma brisa - o ActiveRecord.

O Rails e o ActiveRecord estão bem documentados na Internet, então deixarei uma análise mais profunda deles para outras pessoas mais sábias por enquanto. Hoje, abordarei um aspecto em particular que me tropeçou ao aprender o framework pela primeira vez, para que outros alunos pudessem evitar as mesmas armadilhas: consultas ao banco de dados.

Em um aplicativo Rails, seus modelos, controladores e visualizações combinam forças para fazer um excelente trabalho de salvar coisas no banco de dados, mas eventualmente você precisará extrair essas instâncias de informações para fazer alguma lógica nelas, ou simplesmente exibi-los. É quando as consultas entram em jogo. As consultas no ActiveRecord são essencialmente comandos SQL agrupados em um cobertor quente de sintaxe legível e gravável em Ruby, permitindo que você pense mais sobre o que fará com esses dados, em vez de como recuperá-los.

Existem muitos métodos de consulta específicos para todos os fins, e você pode ler tudo sobre eles na documentação oficial do Rails, mas hoje vou abordar os três mais comuns e as diferenças entre eles, bem como um alguns métodos relacionados semelhantes com exemplos de código contextual:

  1. .encontrar()
  2. .find_by ()
  3. .Onde()

.encontrar()

find () é talvez o método de consulta mais simples de todos, mas, mesmo assim, é um método poderoso. Ele permite recuperar um único objeto do banco de dados relacionado à chave primária (ID) que você transmite como argumento. Digamos que você organizou uma classe que representa um convidado em um programa de entrevistas noturno:

Como cada instância do convidado é salva após a criação, recebe uma chave primária ou ID no banco de dados. Para recuperar essa instância de convidado no futuro, você simplesmente preenche find () na classe Guest dessa maneira (salvando-a em uma variável para fins de exemplo):

O que retornará a instância da classe Guest quando chamada:

O equivalente SQL sendo executado sob o capô para o método find () acima é:

Pode parecer que find () é um método muito específico - afinal, com que frequência você saberá exatamente qual é o ID de uma instância de um objeto no seu banco de dados? Surpreendentemente, você poderá acessar IDs com mais frequência do que pensa, principalmente ao usar parâmetros HTTP no Rails. Mas, ainda assim, serve a um propósito muito específico.

Vale ressaltar que você pode retornar várias instâncias passando uma matriz de chaves primárias como argumento:

Você pode realizar algo semelhante usando:

.leva

que recebe um número como argumento e recupera muitas instâncias da classe em ordem crescente.

Os resultados semelhantes de find () incluem:

.primeiro e último

que recuperam as instâncias mais antigas e mais recentes da classe, respectivamente. Eles também podem receber números como argumentos, retornando muitas instâncias da classe em ordem crescente ou decrescente, respectivamente.

Isso nos leva ao nosso próximo e mais versátil método de consulta: find_by ()

.find_by ()

À primeira vista, .find_by () pode parecer familiar, mas as familiaridades terminam rapidamente. Assim como .find (), .find_by () retorna implicitamente apenas um objeto de uma classe, mas se diferencia permitindo que outros atributos além de uma chave primária sejam pesquisados ​​e permitindo que mais de um atributo seja pesquisado de uma só vez. Por exemplo, você pode encontrar um convidado pesquisando seu nome:

O SQL equivalente aqui é:

Ótimo, recuperamos um objeto! Mas espere, este é Michael J. Fox, o ator, e queríamos encontrar Michael J. Fox, o astronauta! (nota: este é apenas um exemplo, não posso confirmar nem negar a existência de um astronauta chamado Michael J. Fox.)

Para encontrar essa instância, poderíamos especificar mais:

Viva! Graças à nossa capacidade de ajustar nossa pesquisa, encontramos a instância correta da classe Guest. Este é o poder de .find_by (). Teoricamente, você poderia procurar quantos atributos de classe quisesse, a fim de restringir sua pesquisa.

Você também pode usar .find_by () para encontrar classes de marceneiro específicas em seus aplicativos, que é uma ferramenta muito versátil para criar métodos de classe. Digamos que um convidado tenha aparecido em um episódio específico de um programa de entrevistas e que você queria encontrar as informações associadas a essa aparência. Se a nossa classe Aparência existir como tal:

Você pode usar .find_by () para recuperar facilmente essa instância específica do Appearance e inserir essa lógica em qualquer lugar que desejar. Vamos usá-lo como um método de classe para Guest:

Quando usado em uma instância de um Convidado e quando recebe uma instância de um Episódio como argumento, isso retornará a instância daquela Aparência específica. Surpreendente!

“Mas”, você pode estar dizendo, “e se eu quisesse recuperar várias instâncias de uma classe? E se eu quisesse recuperar todos os exemplos de Michael J. Fox, o ator, e Michael J. Fox, o astronauta? ”

Fico feliz que você tenha perguntado, porque é aí que nosso próximo e último método entra em jogo: .where ()

.Onde()

Dos três principais métodos de consulta que abordamos neste post, .where () é possivelmente o mais versátil, mas também o mais complexo e o mais fácil de se confundir.

Enquanto .find () e .find_by () retornam instâncias únicas de um objeto, .where () retorna o que é chamado de "objeto ActiveRecord :: Relation", essencialmente uma matriz de instâncias com algumas informações extras anexadas. Como resultado, a utilização completa de .where () também exigirá um conhecimento mais intermediário do trabalho com matrizes de informações aninhadas.

.where () deve ser pensado como um método de “Condição”, também conhecido como um que permite controlar quais objetos estão sendo retornados, definindo quais “condições” para vasculhar seu banco de dados e limitar o que é retornado. Mais uma vez, incentivo a leitura da documentação do Rails sobre Condições para obter tópicos mais avançados, mas abordarei os casos de uso básicos que você provavelmente precisará .where () para cobrir.

Você pode escrever a sintaxe de uma solicitação .where () de maneira semelhante aos exemplos anteriores para encontrar TODAS as instâncias de convidados chamados Michael J. Fox:

Uau, agora existem ainda mais! Temos Michael J. Fox, o pintor, e Michael J. Fox, o músico também. Com um método simples, temos uma matriz de cada convidado com esse nome - que ferramenta poderosa!

Aqui é onde as coisas ficam interessantes. Se você deseja passar várias condições para uma consulta .where (), a sintaxe mudará para algo menos familiar.

Se houvesse várias instâncias de atores chamados Michael J. Fox, você poderia codificar a consulta de maneira semelhante a uma solicitação .find_by ():

Ou você pode codificá-lo de maneira mais semelhante ao SQL, assim:

Esse fraseado é preferido na maioria dos casos, pois passar os argumentos indiretamente pelos? S permite mais segurança em seus parâmetros e fornece uma camada de proteção contra a injeção de código malicioso. Não é algo para se preocupar logo de cara quando se aprende, mas é importante ter em mente.

Se você quiser recuperar todas as instâncias de Michael J. Fox, o ator OU Michael J. Fox, o astronauta, poderá encadear suas solicitações .where () para criar uma consulta mais complexa:

O encadeamento de solicitações semelhantes usando .or, bem como a capacidade de pesquisar usando um implícito e conforme mencionado acima, fornece .where () um utilitário poderoso quando se trata de vasculhar seu banco de dados e retornar várias instâncias de classes exatamente como você precisa delas .

Agora que aprendemos os três métodos de consulta mais onipresentes do Rails e do ActiveRecord, o próximo passo é praticar e usá-los em seus próprios aplicativos! A referência à documentação do Rails continuará fornecendo orientação e revisão adicional em sua jornada. Boa sorte!