2016-05-30 4 views
1

Mein Code:Wie erstelle ich ein Composable wo mit Ecto?

defmodule Model1 do 
    use Ecto.Schema 
    import Ecto.Query 

    schema "model1" do 
    belongs_to :model2, Model2 
    end 

    def create_query do 
    Model1 
    |> join(:inner, [m1], m2 in assoc(m1, :model2)) 
    end 

    def apply_where(query, %{name: name}) do 
    query 
    |> where([m1, m2], ilike(m2.name, ^name)) 
    end 
end 


defmodule Model2 do 
    use Ecto.Schema 

    schema "model2" do 
    has_many :model1, Model1 
    field :name, :string 
    end 
end 

Wenn ich versuche:

param = %{name: "test"} 
Model1.create_query |> Model1.apply_where(param) |> Repo.all 

Es ist gut funktionieren. Aber ist es eine Möglichkeit, apply_query Funktion wie folgt zu codieren:

def apply_where(query, %{name: name}) do 
    query 
    |> where([m2], ilike(m2.name, ^name)) 
end 

Und wenn meine Abfrage viele hat Klauseln beitreten? Muss ich alle verknüpften Schemata (Tabellen) in der Liste angeben (zuerst wo arg) [m1, m2, m3, ... mx], um jedes Mal ein Feld zu binden?

Antwort

0

Da m2 eine Bindung in einem Join ist, müssen Sie [m1, m2] angeben. Dies ist abhängig von der Position, nicht Name, so dass Ihre apply_where kann [model_1, model_2] und ecto würde immer noch verstehen, was Sie gemeint, obwohl die Bindung andere Namen verwendet.

Nach the docs:

Bindings in Ecto are positional, and the names do not have to be consistent between 
input and refinement queries. 
... 
When composing queries you must specify bindings again for each refinement query. 

jedoch in Fällen, in denen Sie viele haben schließt sich:

You are not required to specify all bindings when composing. 

Und in Zusammensetzungen, in denen Sie nicht besorgt sind über die Verbindungen:

Although bindings are extremely useful when working with joins, they are not 
necessary when the query has only the from clause. 
+0

Danke für die Antwort Cody Poll! In meinem Fall verwende ich die Abfrage für zwei Momente: 1 - Suche Daten mit bestimmten Filtern (Where-Klausel) 2 - Daten durchsuchen, um drei Combobox-Filter im Bildschirm mit einer deutlichen Spalte und ohne Filter in Where-Klausel füllen. Ich versuche, dieselbe Abfrage zu verwenden: Für Combobox benutze ich die Ecto.Query.exclude Funktion, um Select, Order-By und Preload zu entfernen. Wenn Joins bearbeitet werden, habe ich Einfluss auf alle meine "apply_where" -Funktion. Composable-Abfragen sind nicht sinnvoll, da die Bindung positionsabhängig ist und nie benannt wird, wenn sie sich in verschiedenen Bereichen befindet (getrennte Funktionen). –