2017-12-29 11 views
0

私のブログアプリには、他人の投稿をコピーして自分のものとしてホストする機能があります。エリクシールでの関連付けによるエントリーの複製

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

Please preload your associations before manipulating them through changesets

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は非常に少ない仕事のうちの1つです常にです。

+0

この状況では、データの分岐/分岐が望ましいことを明確にする必要があります。新しくコピーされた投稿への変更は、その新しいオーナーのコピーにのみ存在します。これらの要件を前提に、これはまだ最良の方法ですか? –

+1

私たちがどのような変化をしているかによって大きく左右されます。序文、コメント、強調表示を追加する場合は「はい」を選択します。それがテキスト修正に関するものであれば、私は剽窃を感謝することはできません。これはまさに盗作です。だから、私は間違いなく、元の投稿といくつかの "装飾"の周りの参照を持つことに固執するだろう、_clearly distinguished_。おそらく、元の投稿(投稿のバージョンを格納することを意味する)や他の何かに応じて変更を防ぐために、この多対多のテーブルにいくつかのプロパティを追加することがあります。それで – mudasobwa

+1

とにかく、あなたは 'Repo.preload'で動くかもしれませんが、あなたは後でアイデアのために私に感謝するつもりです:) – mudasobwa

関連する問題