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).
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
Altere o schemaBlog.Post
:
defmoduleBlog.PostdouseEcto.Schemaschema"posts"dofield:titlefield:bodyhas_many:comments,Blog.Comment# adicione essa linhaembeds_many:permalinks,Blog.Permalinktimestamps()endend
Gere uma migração pra criar o campopermalinks
:
$mix ecto.gen.migration add_permalinks_to_post
Altere o arquivo de migração:
defmoduleBlog.Repo.Migrations.AddPermalinksToPostdouseEcto.Migrationdefchangedo# adicionando o campo `permalinks` na tabela `posts`altertable(:posts)doadd:permalinks,:jsonbendendend
O:jsonb
já aceita uma lista, então não precisa colocar{:array, :jsonb}
.
$mix ecto.migrate
É 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"}]})
Vamos ver como ficou no banco de dados:
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)
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)
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)
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"}}]
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)

- LocationDonostia-San Sebastian, Spain
- Joined
Show Maiqui Tomé!

Valeeu Romenig :)
For further actions, you may consider blocking this person and/orreporting abuse