Elixir - Como fazer determinadas operações com a biblioteca Ecto (Parte 2)
Wesley de Morais
Posted on January 27, 2023
Vamos para segunda parte do nosso artigo, agora vamos as operações propriamente ditas.
Fazendo Operações no banco de dados
Todas as operações que iremos fazer será usando o shell que o elixir nos oferece, então digite no terminal:
iex -S mix
Operações sem usar Ecto.Schema
Algumas vezes será necessário fazer operações de banco de dados sem a utilização do Ecto.Schema, e apenas usar as tabelas associadas, porém mesmo sem a utilização do Ecto.Schema não vamos necessitar criar o SQL bruto.
Busca
A primeira operação que vamos fazer será a de busca, com o seguinte comando podemos criar uma query para verificar todos os clientes inseridos no nosso banco de dados:
import Ecto.Query
alias PizzariaEcto.Repo
query = from("clients", select: [:name, :phone])
Repo.all(query)
O código acima vai criar o seguinte sql e executa-lo:
SELECT name, phone FROM clients
Como eu falei a um tempo quando criamos a query ela não será executada, pois o Ecto usa o padrão repositório, ou seja, apenas funções do repositório poderá operar em cima do banco de dados. Assim, essa função Repo.all() irá receber uma query(Uma struct Ecto.Query) e retornar uma lista de mapas contendo as informações no banco, mas como não temos nada no banco será retornado uma lista vazia, então vamos inserir algo no banco de dados.
Inserção
data = [
%{name: "Bruno Santos", phone: "999878767"},
%{name: "Maria Pereira", phone: "994657876"},
%{name: "Fábio Bio", phone: "999870900"}
]
Repo.insert_all("clients", data)
#=> {3, nil}
Com esse código inserirmos 3 clientes na nossa base de dados, então podemos novamente executar o comando de busca para ver esses clientes.
Busca específica
Afim de poder executar uma operação de busca específica podemos executar:
import Ecto.Query
alias PizzariaEcto.Repo
query = from(c in "clients", where: c.name == "Bruno Santos", select: [:name, :phone])
Repo.all(query)
Remoção
Afim de poder executar uma operação de remoção de dados podemos executar:
import Ecto.Query
alias PizzariaEcto.Repo
from(c in "clients", where: c.name == "Bruno Santos") |> Repo.delete_all
Atualização
Podemos fazer atualizações também ainda sem usar schemas:
import Ecto.Query
alias PizzariaEcto.Repo
from(c in "clients", where: c.name == "Fábio Bio") |> Repo.update_all
Operações usando o Ecto.Schema
Com os schemas em mãos podemos fazer a mesma coisa que fazermos sem os schemas, porém o retorno dessas operações vão está em estruturas elixir.
Busca
As buscas usando Ecto.Schema é a mesma coisa de sem usa essa estrutura, mas o retorno da função será uma lista de estruturas elixir populadas.
import Ecto.Query
alias PizzariaEcto.{Repo, Client}
query = from(Client)
Repo.all(query)
#=> [%PizzariaEcto.Client{...},...]
Buscas específicas
Podemos fazer retornos em estruturas elixir usando a função Repo.get_by().
import Ecto.Query
alias PizzariaEcto.{Repo, Client}
Repo.get_by(Client, name: "Maria Pereira")
#=> %PizzariaEcto.Client{...}
Ecto.Changeset
Antes de fazermos operações com inserção e atualização de dados usando as estruturas elixir, podemos falar sobre a estrutura Ecto.Changeset. Esta estrutura nos permite criar casts e validações para dados que são inseridos pelo usuário.
alias PizzariaEcto.Client
import Ecto.Changeset
params = %{name: "Mariana Bom", phone: "999808909", email: "mariana@gmail.com"}
changeset = cast(Client, params, [:name, :phone])
Repo.insert(changeset)
A função cast permiti filtrar quais chaves vão poder serem usadas para criação da estrutura PizzariaEcto.Client, e assim usando a função insert inserir no banco de dados. O ecto tem funções de validação como o validate_length que recebe um changeset e retorna um novo changeset com essa validação aplicada, então podemos melhorar o nosso código:
alias PizzariaEcto.Client
import Ecto.Changeset
params = %{name: "Mariana Bom", phone: "999808909", email: "mariana@gmail.com"}
changeset = cast(%Client{}, params, [:name, :phone]) |> validate_length(:phone, min: 9)
Repo.insert(changeset)
O código acima permite inserir apenas os dados de name e phone que tenha no mínimo 9 dígitos, caso alguma validação não ocorra a inserção não funcionará.
Podemos fazer atualizações usando changeset, o seguinte código vai procurar um cliente chamado “Maria Bom”, criar um changeset com base nesse retorno e mandar para a função update para atualizar o banco.
alias PizzariaEcto.{Repo,Client}
import Ecto.Changeset
client = Repo.get_by(Client, name: "Mariana Bom")
changeset = change(client, name: "Mariana Ruim")
Repo.update(changeset)
#=> {:ok, struct_com_cliente_atualizado}
Conclusão
No presente artigo vimos como a ferramenta Ecto nos possibilita fazer operações no banco de dados de nossa preferência. O uso do Ecto também se dá principalmente junto ao framework Phoenix que nos permite criar aplicações web poderosas, afim de resolver alguns problemas existentes.
Referências
Programming Ecto - Build Database Apps in Elixir for Scalability and Performance
Posted on January 27, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.