Elixir 在Phoenix/Exto中更改关联而不使用铸造关联
我正在尝试向Phoenix应用程序添加一个Elixir 在Phoenix/Exto中更改关联而不使用铸造关联,elixir,phoenix-framework,ecto,Elixir,Phoenix Framework,Ecto,我正在尝试向Phoenix应用程序添加一个replicate函数,它接受一个Page对象和一个owner\u id,并创建一个新的页面,该页面具有相同的字段,但由其他人拥有。现在看起来是这样的: def duplicate(%Page{} = page, new_owner_id) when is_integer(new_owner_id) do page |> Page.changeset(%{owner_id: new_owner_id}) |> Re
replicate
函数,它接受一个Page
对象和一个owner\u id
,并创建一个新的页面
,该页面具有相同的字段,但由其他人拥有。现在看起来是这样的:
def duplicate(%Page{} = page, new_owner_id) when is_integer(new_owner_id) do
page
|> Page.changeset(%{owner_id: new_owner_id})
|> Repo.insert()
end
对此进行测试会引发以下错误:
(运行时错误)试图从未加载的“页面”强制转换或更改关联“所有者”。请先预加载关联,然后再通过变更集对其进行操作
我不想操纵用户关联中的字段。我只想更改关联的用户。我相信这应该是可能的,没有铸造协会(有一个关于做这件事),但我不知道如何让错误消失。我错过了什么
规范的其他相关部分(简化):
变更集功能:
def changeset(%Page{} = page, attrs) do
page
|> cast(attrs, [:owner_id])
|> foreign_key_constraint(:owner_id)
end
模式:
schema "pages" do
belongs_to :owner, User
timestamps()
end
迁移:
def change do
create table(:pages) do
add :owner_id, references(:users, on_delete: :nothing)
timestamps()
end
create index(:pages, [:owner_id])
end
宏提供的关联。默认设置是引发错误,但如果希望像普通外键定义一样更改,则可以将
:on_replace
设置为:update
。所以它看起来像:
属于:所有者、用户,[on\u replace::update]
我有一个后续问题:该错误还意味着页面结构已经是从数据库加载的记录。我认为您不希望尝试重新插入相同的记录,而是希望通过params映射从原始页面结构复制数据来创建一个新页面
即使它不是现有记录,而是某种中介%Page{}
(例如,没有主键),您也可以考虑将复制登录名放入复制函数本身:
def duplicate(%Page{example_data: example_data} = original_page, new_owner_id) when is_integer(new_owner_id) do
%Page{}
|> Page.changeset(%{example_data: example_data, owner_id: new_owner_id})
|> Repo.insert()
end