엘릭서: Trabalhando com Ecto Embeds(Campos Json)

OBS: Esse post é uma continuação das . 프로젝트를 시작하기 전에 설정을 시작하고 전면에 대해 전면에 전압을 가하는 것입니다.

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

PostgreSQL 미국은 JSONB 열 조합(embeds_one/3) 및 ARRAY para fornecer esta funcionalidade(JSONB como ARRAY são suportados por padrão e são cidadaos 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 예시:

Crie um arquivo com o conteúdo:

defmodule Blog.Permalink do
  use Ecto.Schema

  embedded_schema do
    field :url
    timestamps
  end
end


대체 스키마Blog.Post:

defmodule Blog.Post do
  use Ecto.Schema

  schema "posts" do
    field :title
    field :body
    has_many :comments, Blog.Comment

    # adicione essa linha
    embeds_many :permalinks, Blog.Permalink

    timestamps()
  end
end


Gere uma migração pra criar o campo permalinks :

$ mix ecto.gen.migration add_permalinks_to_post


Altere o arquivo de migração:

defmodule Blog.Repo.Migrations.AddPermalinksToPost do
  use Ecto.Migration

  def change do
    # adicionando o campo `permalinks` na tabela `posts`
    alter table(:posts) do
      add :permalinks, :jsonb
    end
  end
end


O :jsonb 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 no Ecto.Changeset.put_embed .

# Generate a changeset for the post
changeset = Ecto.Changeset.change(post)

# Let's track the new permalinks
changeset = Ecto.Changeset.put_embed(changeset, :permalinks,
  [%Permalink{url: "example.com/thebest"},
   %Permalink{url: "another.com/mostaccessed"}]
)

# Now insert the post with permalinks at once
post = Repo.insert!(changeset)


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

# Remove all permalinks from example.com
permalinks = Enum.reject post.permalinks, fn permalink ->
  permalink.url =~ "example.com"
end

# Let's create a new changeset
changeset =
  post
  |> Ecto.Changeset.change
  |> Ecto.Changeset.put_embed(:permalinks, permalinks)

# And update the entry
post = Repo.update!(changeset)


Se você não conhece Enum.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. 예를 들어, 다음은 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, acaso, também estivéssemos inserindo um permalink nesta operação, veríamos ali outro changeset com a ação :inserir .

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

좋은 웹페이지 즐겨찾기