2015-04-12 7 views
14

Gibt es eine Möglichkeit, Ecto-Verknüpfungen vorab zu laden, ohne preload explizit zu verwenden :?Ecto-Verknüpfungen standardmäßig vorbelegen

So etwas wie eine Option im Schema?

schema "gadgets" do 
    field :foo, 
    has_many :bars, Myapp.Bar, preload: true 
end 

Ich mache so etwas wie

Repo.get(Gadget, id) 
    |> Repo.preload: [:bars] 

Edit: Der Grund, warum ich versuche, dies zu tun ist, weil ich ein ähnliches Modell auf das bereits vorinstalliert bezogenen Modell vorab zu laden mag, wie

preload: [:invoices preload: :items] 

Antwort

29

Sie auch als Teil einer Abfrage Vorspannung kann:

defmodule Gadget do 
    use Ecto.Model 

    # ... 

    def with_invoices(query) do 
    from q in query, preload: [invoices: :items] 
    end 
end 

Dann:

Gadget 
|> Gadget.with_invoices 
|> Repo.get!(id) 
+7

Gibt es einen Grund, warum es keine Option im Schema ist? Ich weiß, dass es nett ist, die Option beizubehalten, ob bei Abfragen vorgeladen werden soll oder nicht, aber bei bestimmten verwandten Modellen ist es immer vorinstalliert. Bei mir werden die Rechnungssummen aus den Artikeln berechnet, die nicht funktionieren, wenn sie nicht vorgeladen sind. –

-1

Ich bin nicht sicher, es ist der schnellste Weg, aber ich endete dies die after_load Rückruf verwenden zu tun, wie folgt aus:

defmodule Invoice do 
    use Ecto.Model 

    after_load :preload_items 

    def preload_items(invoice) do 
    invoice |> Repo.preload([:items]) 
    end 
end 

Nun ist jedes Mal Rechnung loaded , selbst wenn es von etwas anderem vorgeladen wird, lädt es die zugehörigen Elemente vor.

Bearbeiten - Tu das nicht

stattdessen die Vorbelastungen in der Abfrage Put. Das Abrufen von 1000 Rechnungen mit dem obigen Code führt zu 1 + 1000 Abfragen. Das Preload in der Abfrage fügt 0NE hinzu. Abfrage. 1 + 1 < 1000 + 1.

query = from c in Gadget, 
    #retrieve nested associations adds one query 
    preload: [invoices: :items] 
    select c 

Repo.all(query) 
+4

Tun Sie das nicht. Dies führt eine Abfrage pro Rechnung durch. Wenn Sie also 10 Rechnungen in eine Abfrage laden, werden 10 separate Abfragen zum Laden von Artikeln ausgeführt. –

+0

Vielen Dank, ich wusste, das war schlecht, antworten oben bearbeitet –

+1

Rückrufe wurden von Elixir entfernt – LukeS