在elixir中复制具有关联的条目

时间:2017-12-29 05:42:05

标签: elixir phoenix-framework ecto

我的博客应用程序有一项功能,允许人们复制其他人的帖子,并将其作为自己的帖子托管。

Post与所有者相关联。

  schema "posts" do 
    field :title, :string 
    field :content, :string 

    belongs_to :owner, MyApp.Accounts.User, foreign_key: :owner_id
  end 

我想通过ID获取Post的副本,删除id和owner_id字段,转换新的所有者ID,然后插入。

resolve fn (%{post_id: post_id, new_owner_id: new_owner_id}, _info) ->
  Repo.get!(Post, post_id)
    |> Map.delete(:id)
    |> Map.delete(:owner_id)
    |> Post.changeset(%{owner_id: new_owner_id})
    |> Repo.insert!
end

但是当我这样做时,我收到了这个错误:

Request: POST /api
** (exit) an exception was raised:
    ** (RuntimeError) attempting to cast or change association `owner` from `MyApp.Content.List` that was not loaded. Please preload your associations before manipulating them through changesets

执行此复制的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

正如错误消息中明确提到的那样:

  

请在通过更改集操作之前预先加载您的关联

resolve fn (%{post_id: post_id, new_owner_id: new_owner_id}, _info) ->
  Post
  |> Repo.preload(:owner) # ⇐ this
  |> Repo.get!(post_id)
  |> Map.delete(:id)
  |> Map.delete(:owner_id)
  |> Post.changeset(%{owner_id: new_owner_id})
  |> Repo.insert!
end

旁注:我相信,你做错了。更好的设计是反映“引用”帖子未来可能发生的变化。我宁愿在用户和帖子之间引入新的多对多关系,而不是复制它的内容。 “拷贝”。

按引用复制比按值复制更好。 DRY principle是少数能够始终的人之一。