비약: Trabalhando com Associações no Ecto
Resolvi fazer esse post, para traduzir o post citado acima para o português e adicionar mais detalhes, fazendo um projeto do zero, podendo assim, ajudar programadores iniciantes da linguagem.
O código do projeto você pode encontrar aqui: https://github.com/maiquitome/blog
Neste post, vamos aprender a trabalhar com associações no Ecto, como ler, inserir, atualizar e excluir
associações
e incorporações (embeds)
.프로젝트 설정
Criando o projeto e entrando na pasta do projeto:
$ mix phx.new blog --binary-id && cd blog
Criando o banco de dados:
$ mix ecto.create
Criando os schemas e migrations:
$ mix phx.gen.schema Post posts title body:text
$ mix phx.gen.schema Comment comments post_id:references:posts body:text
협회
As associações no Ecto são usadas quando duas fontes diferentes (tabelas) são ligadas através de chaves estrangeiras (foreign keys).
Um exemplo clássico desta configuração é um post que tem muitos comentários:
defmodule Blog.Post do
use Ecto.Schema
import Ecto.Changeset
@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
schema "posts" do
field :body, :string
field :title, :string
# adicione essa linha
has_many :comments, Blog.Comment
timestamps()
end
@doc false
def changeset(post, attrs) do
post
|> cast(attrs, [:title, :body])
|> validate_required([:title, :body])
end
end
다음 게시물에 대한 의견:
defmodule Blog.Comment do
use Ecto.Schema
import Ecto.Changeset
@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
schema "comments" do
field :body, :string
# remova essa linha
# field :post_id, :binary_id
# adicione essa linha
belongs_to :post, Blog.Post
timestamps()
end
@doc false
def changeset(comment, attrs) do
comment
# adicione o campo :post_id
|> cast(attrs, [:body, :post_id])
|> validate_required([:body])
end
end
인세린도 레지스터
Para gente testar as consultas a seguir, vamos inserir alguns registros.
Criando as tabelas no banco (rodando as migrations):
$ mix ecto.migrate
Vamos criar alguns posts e comentários. Adicione o conteúdo abaixo ao arquivo priv/repo/seeds.ex
:
# Primeiro Post
{:ok, post1} = %Blog.Post{}
|> Blog.Post.changeset(%{title: "Primeiro Post", body: "Conteúdo do primeiro post"})
|> Blog.Repo.insert
%Blog.Comment{}
|> Blog.Comment.changeset(%{body: "comentário do Primeiro Post", post_id: post1.id})
|> Blog.Repo.insert
# Segundo Post
{:ok, post2} = %Blog.Post{}
|> Blog.Post.changeset(%{title: "Segundo Post", body: "Conteúdo do segundo post"})
|> Blog.Repo.insert
%Blog.Comment{}
|> Blog.Comment.changeset(%{body: "comentário do Segundo Post", post_id: post2.id})
|> Blog.Repo.insert
# Terceiro Post
{:ok, post3} = %Blog.Post{}
|> Blog.Post.changeset(%{title: "Terceiro Post", body: "Conteúdo do terceiro post"})
|> Blog.Repo.insert
%Blog.Comment{}
|> Blog.Comment.changeset(%{body: "comentário do Terceiro Post", post_id: post3.id})
|> Blog.Repo.insert
$ mix run priv/repo/seeds.exs
Associações de Consulta(연결 쿼리)
Uma das vantagens de definir associações é que elas podem ser usadas em consultas. Por exemplo:
iex> import Ecto.Query
iex> Blog.Repo.all(from p in Blog.Post, preload: [:comments])
Resultado:
모든 게시물이 게시되지 않은 경우에는 거래처에 의견을 남기지 않습니다. 예를 들어 acima realizará duas Consultas: uma para carregar todos os posts e outra para carregar todos os comentários. Esta éfrequentemente a forma eficiente de carregar associações do banco de dados (mesmo que duas Consultas sejam realizadas), pois precisamos receber e analisar apenas os resultados dos POSTS + COMMENTÁRIOS.
Também é possível pré-carregar (preload) associações usando as uniões enquanto se realizam Consultas mais complexas. 예를 들어, Imagine que tanto os posts como os comentários têm votos e você quer apenas comentários com mais votos do que o próprio post:
Blog.Repo.all from p in Blog.Post,
join: c in assoc(p, :comments),
where: c.votes > p.votes,
preload: [comments: c]
예를 들어 acima agora realizará uma única Consulta, encontrando todos osposts eosrespectivoscommentáriosquecorafamaoscritérios. Como esta Consulta realiza um JOIN, o número de resultados retornados pelo banco de dados é POSTS * COMMENTS, onde o Ecto então processa e associa todos os comentários no post apropriado.
Finalmente, o Ecto também permite que os dados sejam pré-carregados em estruturas (structs) após terem sido carregados através da função Repo.preload/3
:
Blog.Repo.preload posts, :comments
Isto é especialmente útil porque o Ecto não suporta carregamento preguiçoso(지연 로딩). Se você invocar post.comments
e comentários posteriores não tiverem sido pré-carregados, vai retornar Ecto.Association.NotLoaded
. O carregamento preguiçoso é frequencymente uma fonte de confusão e problemas de desempenho eo Ecto pressiona os desenvolvedores a fazerem o que é correto. Portanto, oRepo.preload/3
는 qualquer lugar, qualquer momento에서 명시적 carregadas를 연관시키는 것으로 허용됩니다.
Manipulando Associações
Enquanto o Ecto 2.0 permite inserir um post com múltiplos comentários em uma única operação, por exemplo:
Repo.insert!(%Post{
title: "Hello",
body: "world",
comments: [
%Comment{body: "Excellent!"}
]
})
Muitas vezes você pode querer dividi-lo em etapas diferentes para ter mais flexibilidade no gerenciamento dessas entradas. Por exemplo, você poderia usar conjuntos de mudanças (changesets)
para construir seus posts e comentários ao longo do caminho:
Preste atenção no Ecto.Changeset.put_assoc
.
post = Ecto.Changeset.change(%Post{}, title: "Hello", body: "world")
comment = Ecto.Changeset.change(%Comment{}, body: "Excellent!")
post_with_comments = Ecto.Changeset.put_assoc(post, :comments, [comment])
Repo.insert!(post_with_comments)
Ou manuseando cada entrada individualmente dentro de uma transação:
Preste atenção no Ecto.build_assoc
.
Repo.transaction fn ->
post = Repo.insert!(%Post{title: "Hello", body: "world"})
# Build a comment from the post struct
comment = Ecto.build_assoc(post, :comments, body: "Excellent!")
Repo.insert!(comment)
end
Ecto.build_assoc/3
constrói o comentário utilizando a identificação atualmente definida na estrutura do post. É equivalente a:
%Comment{post_id: post.id, body: "Excellent!"}
A função Ecto.build_assoc/3
é especialmente útil nos controladores (controllers) do Phoenix. Por exemplo, poderíamos ter uma tabela de usuário...
e ao criar um post, faríamos:
Ecto.build_assoc(current_user, :post)
Pois, provavelmente queremos associar o post ao usuário atualmente logado na aplicação.
Em outro controlador, poderíamos construir um comentário para um existente:
Ecto.build_assoc(post, :comments)
O Ecto não fornece funções comopost.comments << comment
que permite misturar dados persistidos com dados não-persistidos. O único mecanismo para mudar tanto o post como os comentários em simultâneo, é por changesets
que iremos explorar quando falarmos sobre incorporações (embeds)
e associações aninhadas (nested associations).
Deletando Associações
Quando definimos um has_many/3
ou has_one/3
, você também pode passar uma opção :on_delete
que especifica qual ação deve ser executada nas associações quando o pai é excluído. Por exemplo, se um post for excluído, então os comentários associados a ele também serão excluídos:
has_many :comments, Blog.Comment, on_delete: :delete_all
Modificando o Schema do post:
defmodule Blog.Post do
use Ecto.Schema
import Ecto.Changeset
@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
schema "posts" do
field :body, :string
field :title, :string
# modifique aqui adicionando `on_delete: :delete_all`
has_many :comments, Blog.Comment, on_delete: :delete_all
timestamps()
end
@doc false
def changeset(post, attrs) do
post
|> cast(attrs, [:title, :body])
|> validate_required([:title, :body])
end
end
Além disso, :nilify_all
também é suportado, sendo que :nothing
é o padrão. Verifique has_many/3
더 많은 정보를 제공하는 문서입니다.
O uso desta opção é DESENCORAJADA para a maioria dos bancos de dados relacionais. Ao invés disso, em sua migração, defina references(:parent_id, on_delete: :delete_all)
:
defmodule Blog.Repo.Migrations.CreateComments do
use Ecto.Migration
def change do
create table(:comments, primary_key: false) do
add :id, :binary_id, primary_key: true
add :body, :text
# modifique aqui adicionando :delete_all
add :post_id, references(:posts, on_delete: :delete_all, type: :binary_id)
timestamps()
end
create index(:comments, [:post_id])
end
end
퍼가기
Acesse a continuação
Reference
이 문제에 관하여(비약: Trabalhando com Associações no Ecto), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/maiquitome/elixir-trabalhando-com-associacoes-no-ecto-d34
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
$ mix phx.new blog --binary-id && cd blog
$ mix ecto.create
$ mix phx.gen.schema Post posts title body:text
$ mix phx.gen.schema Comment comments post_id:references:posts body:text
As associações no Ecto são usadas quando duas fontes diferentes (tabelas) são ligadas através de chaves estrangeiras (foreign keys).
Um exemplo clássico desta configuração é um post que tem muitos comentários:
defmodule Blog.Post do
use Ecto.Schema
import Ecto.Changeset
@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
schema "posts" do
field :body, :string
field :title, :string
# adicione essa linha
has_many :comments, Blog.Comment
timestamps()
end
@doc false
def changeset(post, attrs) do
post
|> cast(attrs, [:title, :body])
|> validate_required([:title, :body])
end
end
다음 게시물에 대한 의견:
defmodule Blog.Comment do
use Ecto.Schema
import Ecto.Changeset
@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
schema "comments" do
field :body, :string
# remova essa linha
# field :post_id, :binary_id
# adicione essa linha
belongs_to :post, Blog.Post
timestamps()
end
@doc false
def changeset(comment, attrs) do
comment
# adicione o campo :post_id
|> cast(attrs, [:body, :post_id])
|> validate_required([:body])
end
end
인세린도 레지스터
Para gente testar as consultas a seguir, vamos inserir alguns registros.
Criando as tabelas no banco (rodando as migrations):
$ mix ecto.migrate
Vamos criar alguns posts e comentários. Adicione o conteúdo abaixo ao arquivo priv/repo/seeds.ex
:
# Primeiro Post
{:ok, post1} = %Blog.Post{}
|> Blog.Post.changeset(%{title: "Primeiro Post", body: "Conteúdo do primeiro post"})
|> Blog.Repo.insert
%Blog.Comment{}
|> Blog.Comment.changeset(%{body: "comentário do Primeiro Post", post_id: post1.id})
|> Blog.Repo.insert
# Segundo Post
{:ok, post2} = %Blog.Post{}
|> Blog.Post.changeset(%{title: "Segundo Post", body: "Conteúdo do segundo post"})
|> Blog.Repo.insert
%Blog.Comment{}
|> Blog.Comment.changeset(%{body: "comentário do Segundo Post", post_id: post2.id})
|> Blog.Repo.insert
# Terceiro Post
{:ok, post3} = %Blog.Post{}
|> Blog.Post.changeset(%{title: "Terceiro Post", body: "Conteúdo do terceiro post"})
|> Blog.Repo.insert
%Blog.Comment{}
|> Blog.Comment.changeset(%{body: "comentário do Terceiro Post", post_id: post3.id})
|> Blog.Repo.insert
$ mix run priv/repo/seeds.exs
Associações de Consulta(연결 쿼리)
Uma das vantagens de definir associações é que elas podem ser usadas em consultas. Por exemplo:
iex> import Ecto.Query
iex> Blog.Repo.all(from p in Blog.Post, preload: [:comments])
Resultado:
모든 게시물이 게시되지 않은 경우에는 거래처에 의견을 남기지 않습니다. 예를 들어 acima realizará duas Consultas: uma para carregar todos os posts e outra para carregar todos os comentários. Esta éfrequentemente a forma eficiente de carregar associações do banco de dados (mesmo que duas Consultas sejam realizadas), pois precisamos receber e analisar apenas os resultados dos POSTS + COMMENTÁRIOS.
Também é possível pré-carregar (preload) associações usando as uniões enquanto se realizam Consultas mais complexas. 예를 들어, Imagine que tanto os posts como os comentários têm votos e você quer apenas comentários com mais votos do que o próprio post:
Blog.Repo.all from p in Blog.Post,
join: c in assoc(p, :comments),
where: c.votes > p.votes,
preload: [comments: c]
예를 들어 acima agora realizará uma única Consulta, encontrando todos osposts eosrespectivoscommentáriosquecorafamaoscritérios. Como esta Consulta realiza um JOIN, o número de resultados retornados pelo banco de dados é POSTS * COMMENTS, onde o Ecto então processa e associa todos os comentários no post apropriado.
Finalmente, o Ecto também permite que os dados sejam pré-carregados em estruturas (structs) após terem sido carregados através da função Repo.preload/3
:
Blog.Repo.preload posts, :comments
Isto é especialmente útil porque o Ecto não suporta carregamento preguiçoso(지연 로딩). Se você invocar post.comments
e comentários posteriores não tiverem sido pré-carregados, vai retornar Ecto.Association.NotLoaded
. O carregamento preguiçoso é frequencymente uma fonte de confusão e problemas de desempenho eo Ecto pressiona os desenvolvedores a fazerem o que é correto. Portanto, oRepo.preload/3
는 qualquer lugar, qualquer momento에서 명시적 carregadas를 연관시키는 것으로 허용됩니다.
Manipulando Associações
Enquanto o Ecto 2.0 permite inserir um post com múltiplos comentários em uma única operação, por exemplo:
Repo.insert!(%Post{
title: "Hello",
body: "world",
comments: [
%Comment{body: "Excellent!"}
]
})
Muitas vezes você pode querer dividi-lo em etapas diferentes para ter mais flexibilidade no gerenciamento dessas entradas. Por exemplo, você poderia usar conjuntos de mudanças (changesets)
para construir seus posts e comentários ao longo do caminho:
Preste atenção no Ecto.Changeset.put_assoc
.
post = Ecto.Changeset.change(%Post{}, title: "Hello", body: "world")
comment = Ecto.Changeset.change(%Comment{}, body: "Excellent!")
post_with_comments = Ecto.Changeset.put_assoc(post, :comments, [comment])
Repo.insert!(post_with_comments)
Ou manuseando cada entrada individualmente dentro de uma transação:
Preste atenção no Ecto.build_assoc
.
Repo.transaction fn ->
post = Repo.insert!(%Post{title: "Hello", body: "world"})
# Build a comment from the post struct
comment = Ecto.build_assoc(post, :comments, body: "Excellent!")
Repo.insert!(comment)
end
Ecto.build_assoc/3
constrói o comentário utilizando a identificação atualmente definida na estrutura do post. É equivalente a:
%Comment{post_id: post.id, body: "Excellent!"}
A função Ecto.build_assoc/3
é especialmente útil nos controladores (controllers) do Phoenix. Por exemplo, poderíamos ter uma tabela de usuário...
e ao criar um post, faríamos:
Ecto.build_assoc(current_user, :post)
Pois, provavelmente queremos associar o post ao usuário atualmente logado na aplicação.
Em outro controlador, poderíamos construir um comentário para um existente:
Ecto.build_assoc(post, :comments)
O Ecto não fornece funções comopost.comments << comment
que permite misturar dados persistidos com dados não-persistidos. O único mecanismo para mudar tanto o post como os comentários em simultâneo, é por changesets
que iremos explorar quando falarmos sobre incorporações (embeds)
e associações aninhadas (nested associations).
Deletando Associações
Quando definimos um has_many/3
ou has_one/3
, você também pode passar uma opção :on_delete
que especifica qual ação deve ser executada nas associações quando o pai é excluído. Por exemplo, se um post for excluído, então os comentários associados a ele também serão excluídos:
has_many :comments, Blog.Comment, on_delete: :delete_all
Modificando o Schema do post:
defmodule Blog.Post do
use Ecto.Schema
import Ecto.Changeset
@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
schema "posts" do
field :body, :string
field :title, :string
# modifique aqui adicionando `on_delete: :delete_all`
has_many :comments, Blog.Comment, on_delete: :delete_all
timestamps()
end
@doc false
def changeset(post, attrs) do
post
|> cast(attrs, [:title, :body])
|> validate_required([:title, :body])
end
end
Além disso, :nilify_all
também é suportado, sendo que :nothing
é o padrão. Verifique has_many/3
더 많은 정보를 제공하는 문서입니다.
O uso desta opção é DESENCORAJADA para a maioria dos bancos de dados relacionais. Ao invés disso, em sua migração, defina references(:parent_id, on_delete: :delete_all)
:
defmodule Blog.Repo.Migrations.CreateComments do
use Ecto.Migration
def change do
create table(:comments, primary_key: false) do
add :id, :binary_id, primary_key: true
add :body, :text
# modifique aqui adicionando :delete_all
add :post_id, references(:posts, on_delete: :delete_all, type: :binary_id)
timestamps()
end
create index(:comments, [:post_id])
end
end
퍼가기
Acesse a continuação
Reference
이 문제에 관하여(비약: Trabalhando com Associações no Ecto), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/maiquitome/elixir-trabalhando-com-associacoes-no-ecto-d34
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
$ mix ecto.migrate
priv/repo/seeds.ex
:# Primeiro Post
{:ok, post1} = %Blog.Post{}
|> Blog.Post.changeset(%{title: "Primeiro Post", body: "Conteúdo do primeiro post"})
|> Blog.Repo.insert
%Blog.Comment{}
|> Blog.Comment.changeset(%{body: "comentário do Primeiro Post", post_id: post1.id})
|> Blog.Repo.insert
# Segundo Post
{:ok, post2} = %Blog.Post{}
|> Blog.Post.changeset(%{title: "Segundo Post", body: "Conteúdo do segundo post"})
|> Blog.Repo.insert
%Blog.Comment{}
|> Blog.Comment.changeset(%{body: "comentário do Segundo Post", post_id: post2.id})
|> Blog.Repo.insert
# Terceiro Post
{:ok, post3} = %Blog.Post{}
|> Blog.Post.changeset(%{title: "Terceiro Post", body: "Conteúdo do terceiro post"})
|> Blog.Repo.insert
%Blog.Comment{}
|> Blog.Comment.changeset(%{body: "comentário do Terceiro Post", post_id: post3.id})
|> Blog.Repo.insert
$ mix run priv/repo/seeds.exs
Uma das vantagens de definir associações é que elas podem ser usadas em consultas. Por exemplo:
iex> import Ecto.Query
iex> Blog.Repo.all(from p in Blog.Post, preload: [:comments])
모든 게시물이 게시되지 않은 경우에는 거래처에 의견을 남기지 않습니다. 예를 들어 acima realizará duas Consultas: uma para carregar todos os posts e outra para carregar todos os comentários. Esta éfrequentemente a forma eficiente de carregar associações do banco de dados (mesmo que duas Consultas sejam realizadas), pois precisamos receber e analisar apenas os resultados dos POSTS + COMMENTÁRIOS.
Também é possível pré-carregar (preload) associações usando as uniões enquanto se realizam Consultas mais complexas. 예를 들어, Imagine que tanto os posts como os comentários têm votos e você quer apenas comentários com mais votos do que o próprio post:
Blog.Repo.all from p in Blog.Post,
join: c in assoc(p, :comments),
where: c.votes > p.votes,
preload: [comments: c]
예를 들어 acima agora realizará uma única Consulta, encontrando todos osposts eosrespectivoscommentáriosquecorafamaoscritérios. Como esta Consulta realiza um JOIN, o número de resultados retornados pelo banco de dados é POSTS * COMMENTS, onde o Ecto então processa e associa todos os comentários no post apropriado.
Finalmente, o Ecto também permite que os dados sejam pré-carregados em estruturas (structs) após terem sido carregados através da função
Repo.preload/3
:Blog.Repo.preload posts, :comments
Isto é especialmente útil porque o Ecto não suporta carregamento preguiçoso(지연 로딩). Se você invocar
post.comments
e comentários posteriores não tiverem sido pré-carregados, vai retornar Ecto.Association.NotLoaded
. O carregamento preguiçoso é frequencymente uma fonte de confusão e problemas de desempenho eo Ecto pressiona os desenvolvedores a fazerem o que é correto. Portanto, oRepo.preload/3
는 qualquer lugar, qualquer momento에서 명시적 carregadas를 연관시키는 것으로 허용됩니다.Manipulando Associações
Enquanto o Ecto 2.0 permite inserir um post com múltiplos comentários em uma única operação, por exemplo:
Repo.insert!(%Post{
title: "Hello",
body: "world",
comments: [
%Comment{body: "Excellent!"}
]
})
Muitas vezes você pode querer dividi-lo em etapas diferentes para ter mais flexibilidade no gerenciamento dessas entradas. Por exemplo, você poderia usar conjuntos de mudanças (changesets)
para construir seus posts e comentários ao longo do caminho:
Preste atenção no Ecto.Changeset.put_assoc
.
post = Ecto.Changeset.change(%Post{}, title: "Hello", body: "world")
comment = Ecto.Changeset.change(%Comment{}, body: "Excellent!")
post_with_comments = Ecto.Changeset.put_assoc(post, :comments, [comment])
Repo.insert!(post_with_comments)
Ou manuseando cada entrada individualmente dentro de uma transação:
Preste atenção no Ecto.build_assoc
.
Repo.transaction fn ->
post = Repo.insert!(%Post{title: "Hello", body: "world"})
# Build a comment from the post struct
comment = Ecto.build_assoc(post, :comments, body: "Excellent!")
Repo.insert!(comment)
end
Ecto.build_assoc/3
constrói o comentário utilizando a identificação atualmente definida na estrutura do post. É equivalente a:
%Comment{post_id: post.id, body: "Excellent!"}
A função Ecto.build_assoc/3
é especialmente útil nos controladores (controllers) do Phoenix. Por exemplo, poderíamos ter uma tabela de usuário...
e ao criar um post, faríamos:
Ecto.build_assoc(current_user, :post)
Pois, provavelmente queremos associar o post ao usuário atualmente logado na aplicação.
Em outro controlador, poderíamos construir um comentário para um existente:
Ecto.build_assoc(post, :comments)
O Ecto não fornece funções comopost.comments << comment
que permite misturar dados persistidos com dados não-persistidos. O único mecanismo para mudar tanto o post como os comentários em simultâneo, é por changesets
que iremos explorar quando falarmos sobre incorporações (embeds)
e associações aninhadas (nested associations).
Deletando Associações
Quando definimos um has_many/3
ou has_one/3
, você também pode passar uma opção :on_delete
que especifica qual ação deve ser executada nas associações quando o pai é excluído. Por exemplo, se um post for excluído, então os comentários associados a ele também serão excluídos:
has_many :comments, Blog.Comment, on_delete: :delete_all
Modificando o Schema do post:
defmodule Blog.Post do
use Ecto.Schema
import Ecto.Changeset
@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
schema "posts" do
field :body, :string
field :title, :string
# modifique aqui adicionando `on_delete: :delete_all`
has_many :comments, Blog.Comment, on_delete: :delete_all
timestamps()
end
@doc false
def changeset(post, attrs) do
post
|> cast(attrs, [:title, :body])
|> validate_required([:title, :body])
end
end
Além disso, :nilify_all
também é suportado, sendo que :nothing
é o padrão. Verifique has_many/3
더 많은 정보를 제공하는 문서입니다.
O uso desta opção é DESENCORAJADA para a maioria dos bancos de dados relacionais. Ao invés disso, em sua migração, defina references(:parent_id, on_delete: :delete_all)
:
defmodule Blog.Repo.Migrations.CreateComments do
use Ecto.Migration
def change do
create table(:comments, primary_key: false) do
add :id, :binary_id, primary_key: true
add :body, :text
# modifique aqui adicionando :delete_all
add :post_id, references(:posts, on_delete: :delete_all, type: :binary_id)
timestamps()
end
create index(:comments, [:post_id])
end
end
퍼가기
Acesse a continuação
Reference
이 문제에 관하여(비약: Trabalhando com Associações no Ecto), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/maiquitome/elixir-trabalhando-com-associacoes-no-ecto-d34
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Repo.insert!(%Post{
title: "Hello",
body: "world",
comments: [
%Comment{body: "Excellent!"}
]
})
conjuntos de mudanças (changesets)
para construir seus posts e comentários ao longo do caminho:Ecto.Changeset.put_assoc
.post = Ecto.Changeset.change(%Post{}, title: "Hello", body: "world")
comment = Ecto.Changeset.change(%Comment{}, body: "Excellent!")
post_with_comments = Ecto.Changeset.put_assoc(post, :comments, [comment])
Repo.insert!(post_with_comments)
Ecto.build_assoc
.Repo.transaction fn ->
post = Repo.insert!(%Post{title: "Hello", body: "world"})
# Build a comment from the post struct
comment = Ecto.build_assoc(post, :comments, body: "Excellent!")
Repo.insert!(comment)
end
Ecto.build_assoc/3
constrói o comentário utilizando a identificação atualmente definida na estrutura do post. É equivalente a:%Comment{post_id: post.id, body: "Excellent!"}
Ecto.build_assoc/3
é especialmente útil nos controladores (controllers) do Phoenix. Por exemplo, poderíamos ter uma tabela de usuário...Ecto.build_assoc(current_user, :post)
Ecto.build_assoc(post, :comments)
Quando definimos um has_many/3
ou has_one/3
, você também pode passar uma opção :on_delete
que especifica qual ação deve ser executada nas associações quando o pai é excluído. Por exemplo, se um post for excluído, então os comentários associados a ele também serão excluídos:
has_many :comments, Blog.Comment, on_delete: :delete_all
Modificando o Schema do post:
defmodule Blog.Post do
use Ecto.Schema
import Ecto.Changeset
@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
schema "posts" do
field :body, :string
field :title, :string
# modifique aqui adicionando `on_delete: :delete_all`
has_many :comments, Blog.Comment, on_delete: :delete_all
timestamps()
end
@doc false
def changeset(post, attrs) do
post
|> cast(attrs, [:title, :body])
|> validate_required([:title, :body])
end
end
:nilify_all
também é suportado, sendo que :nothing
é o padrão. Verifique has_many/3
더 많은 정보를 제공하는 문서입니다.O uso desta opção é DESENCORAJADA para a maioria dos bancos de dados relacionais. Ao invés disso, em sua migração, defina
references(:parent_id, on_delete: :delete_all)
:defmodule Blog.Repo.Migrations.CreateComments do
use Ecto.Migration
def change do
create table(:comments, primary_key: false) do
add :id, :binary_id, primary_key: true
add :body, :text
# modifique aqui adicionando :delete_all
add :post_id, references(:posts, on_delete: :delete_all, type: :binary_id)
timestamps()
end
create index(:comments, [:post_id])
end
end
퍼가기
Acesse a continuação
Reference
이 문제에 관하여(비약: Trabalhando com Associações no Ecto), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/maiquitome/elixir-trabalhando-com-associacoes-no-ecto-d34
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(비약: Trabalhando com Associações no Ecto), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/maiquitome/elixir-trabalhando-com-associacoes-no-ecto-d34텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)