Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Dev Maiqui 🇧🇷
Dev Maiqui 🇧🇷

Posted on • Edited on

     

💧 Elixir: Trabalhando com Ecto Embeds (Campos Json)

OBS: Esse post é uma continuação dasassociações. Se você não fez o setup do projeto, você pode voltar para o post anterior para fazê-lo.

Além das associações, o Ecto também suportaembeds (incorporações) em alguns bancos de dados. Comembeds, o filho é incorporado no pai, em vez de ser armazenado em outra tabela.

Bancos de dados como o PostgreSQL usa uma combinação de colunasJSONB (embeds_one/3) eARRAY para fornecer esta funcionalidade (tanto JSONB como ARRAY são suportados por padrão e são cidadãos de primeira classe no Ecto).

A Jornada do Autodidata em Inglês

Trabalhar comembeds é na maioria das vezes o mesmo que trabalhar com outro campo em umschema, exceto quando se trata de manipulá-los. Vamos ver um exemplo:

Crie um arquivo com o conteúdo:

defmoduleBlog.PermalinkdouseEcto.Schemaembedded_schemadofield:urltimestampsendend
Enter fullscreen modeExit fullscreen mode

Altere o schemaBlog.Post:

defmoduleBlog.PostdouseEcto.Schemaschema"posts"dofield:titlefield:bodyhas_many:comments,Blog.Comment# adicione essa linhaembeds_many:permalinks,Blog.Permalinktimestamps()endend
Enter fullscreen modeExit fullscreen mode

Gere uma migração pra criar o campopermalinks:

$mix ecto.gen.migration add_permalinks_to_post
Enter fullscreen modeExit fullscreen mode

Altere o arquivo de migração:

defmoduleBlog.Repo.Migrations.AddPermalinksToPostdouseEcto.Migrationdefchangedo# adicionando o campo `permalinks` na tabela `posts`altertable(:posts)doadd:permalinks,:jsonbendendend
Enter fullscreen modeExit fullscreen mode

O:jsonb já aceita uma lista, então não precisa colocar{:array, :jsonb}.

$mix ecto.migrate
Enter fullscreen modeExit fullscreen mode

É possível inserir diretamente um post com múltiplos permalinks:

iex>Blog.Repo.insert!(%Blog.Post{title:"Hello",permalinks:[%Blog.Permalink{url:"example.com/thebest"},%Blog.Permalink{url:"another.com/mostaccessed"}]})
Enter fullscreen modeExit fullscreen mode

Image description

Vamos ver como ficou no banco de dados:

Image description

Image description

Semelhante às associações, você também pode gerenciar essas entradas usandochangesets (conjuntos de alterações):

Preste atenção noEcto.Changeset.put_embed.

# Generate a changeset for the postchangeset=Ecto.Changeset.change(post)# Let's track the new permalinkschangeset=Ecto.Changeset.put_embed(changeset,:permalinks,[%Permalink{url:"example.com/thebest"},%Permalink{url:"another.com/mostaccessed"}])# Now insert the post with permalinks at oncepost=Repo.insert!(changeset)
Enter fullscreen modeExit fullscreen mode

Se você quiser substituir ou remover um permalink em particular, você pode trabalhar com permalinks como coleção e depois simplesmente colocá-lo como uma mudança novamente:

# Remove all permalinks from example.compermalinks=Enum.rejectpost.permalinks,fnpermalink->permalink.url=~"example.com"end# Let's create a new changesetchangeset=post|>Ecto.Changeset.change|>Ecto.Changeset.put_embed(:permalinks,permalinks)# And update the entrypost=Repo.update!(changeset)
Enter fullscreen modeExit fullscreen mode

Se você não conheceEnum.reject,veja aqui como funciona de forma visual.

A beleza de trabalhar com os changesets é que eles acompanham todas as mudanças que serão enviadas para o banco de dados e nós podemos introspectá-los a qualquer momento. Por exemplo, se chamássemos antesRepo.update!/3:

IO.inspect(changeset.changes.permalinks)
Enter fullscreen modeExit fullscreen mode

Nós veríamos algo parecido:

[%Ecto.Changeset{action::delete,changes:%{},model:%Permalink{url:"example.com/thebest"}},%Ecto.Changeset{action::update,changes:%{},model:%Permalink{url:"another.com/mostaccessed"}}]
Enter fullscreen modeExit fullscreen mode

Se, por acaso, também estivéssemos inserindo um permalink nesta operação, veríamos ali outro changeset com a ação:inserir.

Os changesets contêm uma visão completa do que está mudando, como eles estão mudando e você pode manipulá-los diretamente.

Top comments(2)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
romenigld profile image
Romenig Lima Damasio
Interested on Elixir, Phoenix, RoR, Javascript.
  • Location
    Donostia-San Sebastian, Spain
  • Joined

Show Maiqui Tomé!

CollapseExpand
 
maiquitome profile image
Dev Maiqui 🇧🇷
youtube.com/@DevMaiqui

Valeeu Romenig :)

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

youtube.com/@DevMaiqui
  • Location
    Flores da Cunha/RS, Brasil
  • Joined

More fromDev Maiqui 🇧🇷

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp