如何更新 Ecto 中的一对多关联
How to update one to many association in Ecto
在我的应用中,节目和剧集之间存在一对多关系。节目可以有很多集。创建剧集时,我可以通过这样做与节目建立关联:
def create(conn, %{"episode" => episode_params}) do
show = Repo.get!(Show, episode_params["show_id"])
changeset =
show
|> build_assoc(:episodes)
|> Episode.changeset(episode_params)
case Repo.insert(changeset) do
{:ok, _post} ->
conn
|> put_flash(:info, "Episode created successfully.")
|> redirect(to: show_path(conn, :show, show))
{:error, changeset} ->
render(conn, "new.html", changeset: changeset)
end
end
如何才能最好地将剧集关联更新到节目?这就是我现在拥有的。
def update(conn, %{"id" => id, "episode" => episode_params}) do
episode = Repo.get!(Episode, id)
changeset = Episode.changeset(episode, episode_params)
case Repo.update(changeset) do
{:ok, episode} ->
conn
|> put_flash(:info, "Episode updated successfully.")
|> redirect(to: episode_path(conn, :show, episode))
{:error, changeset} ->
render(conn, "edit.html", episode: episode, changeset: changeset)
end
end
除非您有一些要求,例如不允许从某些操作更改 show_id
,最简单的方法是将 show_id
添加到 [=16= 调用中的允许字段列表中] 在 Episode.changeset/2
中,让数据库使用外键约束处理无效的 show_id
值。
defmodule MyApp.Episode
...
def changeset(struct, params \ %{}) do
struct
|> cast(params, [:show_id, ...]) # add :show_id here
end
end
然后直接将 episode_params
传递给 create
和 update
中的 changeset
:
def create(conn, %{"episode" => episode_params}) do
changeset = Episode.changeset(%Episode{}, episode_params)
...
end
def update(conn, %{"id" => id, "episode" => episode_params}) do
episode = Repo.get!(Episode, id)
changeset = Episode.changeset(episode, episode_params)
...
end
确保您的迁移使用 references(...)
添加了 show_id
字段,或者您手动添加了数据库约束。类似于:
create table(:episodes) do
...
add :show_id, references(:shows, on_delete: :nothing)
...
end
在我的应用中,节目和剧集之间存在一对多关系。节目可以有很多集。创建剧集时,我可以通过这样做与节目建立关联:
def create(conn, %{"episode" => episode_params}) do
show = Repo.get!(Show, episode_params["show_id"])
changeset =
show
|> build_assoc(:episodes)
|> Episode.changeset(episode_params)
case Repo.insert(changeset) do
{:ok, _post} ->
conn
|> put_flash(:info, "Episode created successfully.")
|> redirect(to: show_path(conn, :show, show))
{:error, changeset} ->
render(conn, "new.html", changeset: changeset)
end
end
如何才能最好地将剧集关联更新到节目?这就是我现在拥有的。
def update(conn, %{"id" => id, "episode" => episode_params}) do
episode = Repo.get!(Episode, id)
changeset = Episode.changeset(episode, episode_params)
case Repo.update(changeset) do
{:ok, episode} ->
conn
|> put_flash(:info, "Episode updated successfully.")
|> redirect(to: episode_path(conn, :show, episode))
{:error, changeset} ->
render(conn, "edit.html", episode: episode, changeset: changeset)
end
end
除非您有一些要求,例如不允许从某些操作更改 show_id
,最简单的方法是将 show_id
添加到 [=16= 调用中的允许字段列表中] 在 Episode.changeset/2
中,让数据库使用外键约束处理无效的 show_id
值。
defmodule MyApp.Episode
...
def changeset(struct, params \ %{}) do
struct
|> cast(params, [:show_id, ...]) # add :show_id here
end
end
然后直接将 episode_params
传递给 create
和 update
中的 changeset
:
def create(conn, %{"episode" => episode_params}) do
changeset = Episode.changeset(%Episode{}, episode_params)
...
end
def update(conn, %{"id" => id, "episode" => episode_params}) do
episode = Repo.get!(Episode, id)
changeset = Episode.changeset(episode, episode_params)
...
end
确保您的迁移使用 references(...)
添加了 show_id
字段,或者您手动添加了数据库约束。类似于:
create table(:episodes) do
...
add :show_id, references(:shows, on_delete: :nothing)
...
end