2016-12-08 6 views
1

私は3レベルの階層モデル関係を持っています。すなわち、model1model2に属し、model2model3に属します。複数階層モデルを事前にロードできません

my_models = Repo.all(Model1) 
    |> Enum.map(fn (x) -> 
     Repo.preload(x, :model2) 
    end) 
    |> Enum.map(fn(x) -> # error "no function clause matching in Ecto.Repo.Preloader.preload/4" 
     Repo.preload(x.model2, :model3) 
    end) 

エラーがある "Ecto.Repo.Preloader.preloadで機能なし句マッチング/ 4"

+1

は、なぜあなたは 'Enum.map'にプリロードされていますか?それはプリロードの全目的を破っています。なぜRepo.all(Model1)|> Repo.preload(model2:[:model3]) '? – Dogbert

+0

@Dogbertは、単一のエンティティでのみ作業をプリロードしませんか? – Kooooro

+0

Nopeはリストにも同様に機能し、ネストされた関連付けを効率的に読み込むこともサポートしています。 – Dogbert

答えて

0

あなた:私はmodel1ためmodel2model3をプリロードしようとしている

することができます:

my_models = Repo.all(Model1) |> Repo.preload(model2: :model3) 

これは同じではありません:

my_models = Repo.all(Model1) |> Repo.preload([:model2, :model3]) 

としては、エラーメッセージの多くを提供できる場合、私はあなたがそのエラーメッセージを取得している理由を説明することができるでしょうhttps://hexdocs.pm/ecto/Ecto.Query.html#preload/3

で説明しました。 model2(第2のEnum.map)はnilであり、https://github.com/elixir-ecto/ecto/blob/66e90c97054cd855c7cbb694bc79a0b9313f119b/lib/ecto/repo/preloader.ex#L36mapまたはlistとしか動作しない可能性があります。

上記のようにネストされたプリロードを使用すると、このケースが処理されます。

+0

は動作しませんが、プリロードされていません。ドキュメンテーションのように「所有」から「has_many」ではないからでしょうか? – Kooooro

+0

これは間違いなく両方で動作するはずです。問題を特定するのに役立つように、あなたのスキーマと 'Repo.preload(model1、model2 :: model3)'を実行した結果を投稿してもらえますか? – Gazler

+0

the:model3がロードされていない、私はModel3 - > Model1 "has_many through" inか何かを持っていればいいですか? – Kooooro

0
Repo.preload([{:model2, :model3}]) 

このトリックを行う必要があります。あなたはこの構造をネストすることができますが、深く望みます。例えば。深い5つのモデル:

Repo.preload([ 
    {:model1, [ 
    {:model2, [ 
     {:model3, [ 
     {:model4, :model5} 
     ]} 
    ]} 
    ]} 
]) 
+0

が機能しません... – Kooooro

+0

モデル2がロードされています、モデル3は – Kooooro

+0

ではありません。参照['{model2、:model3}]'は '[model2::model3]'と全く同じですhttp:// elixir-lang.org/getting-started/keywords-and-maps.html#keyword-lists – Gazler

関連する問題