Elixir 在Phoenix/Exto中更改关联而不使用铸造关联

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

我正在尝试向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})
    |> 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