In Ecto si possono fare interrogazioni riutilizzabili/componibili in questo modo:Elixir Ecto: più join e/query componibili riutilizzabili
defmodule AModel
#...
def anonymous(q), do: q |> where([am], is_null(am.user_id))
end
Vedi altri esempi on this blog post.
Tuttavia, devo affrontare un problema utilizzando più join.
Supponiamo di avere uno schema che assomiglia a questo:
- Amodel appartiene alla BModel
- BModel appartiene alla CModel
- CModel appartiene alla DModel
La soluzione proposta in questo l'articolo non funziona davvero con i join profondi:
q = DModel
|> join(:inner, [dm], cm in assoc(dm, :c_models))
|> join(:inner, [_, cm], bm in assoc(cm, :b_models))
|> join(:inner, [_, _, bm], am in assoc(bm, :a_models))
|> AModel.anonymous
Le funzioni di query prendono come primo argomento (secondo per join) una tabella di associazione. Contiene i precedenti join ed è purtroppo stretto per unire l'ordine.
Nel nostro caso, la funzione anonymous
ha come destinazione la tabella di partenza. Tuttavia, nell'esempio di query, AModel è il 4o legame ...
Qualche idea o tecnica per sbarazzarsi di questa dipendenza dall'ordine?
EDIT:
ricevo una risposta dal blog dell'autore. Mi ha detto che non esiste un altro modo nativo per gestire i binding rispetto alla posizione nella tabella. Ha anche dato this article evidenziando questo fatto.
Ma per amor di dio, se l'ordine conta solo, perché non riesco a creare sopra di esso una mappatura dei nomi che associa il nome all'indice vincolante?
È troppo chiedere: p?
Uno dei creatori di Ecto qui. Questo è in realtà un problema molto difficile da risolvere perché, finché leghiamo i nomi, la possibilità di conflitti aumenta notevolmente, specialmente perché amiamo usare scorciatoie, come hai usato am, bm e così via. Ma sappiamo che l'affare attuale è anche un fastidio, ma non abbiamo ancora una buona soluzione (ancora). –
Stavo pensando di provare a creare una sovrapposizione sopra l'elenco di rilegature. Quando si effettua il join, posso dare un nome di simbolo che corrisponde alla posizione di rilegatura. Quindi, usando 'where', posso estrarre l'associazione richiesta fornendo il nome. Pensi che sia attualmente possibile creare tale meccanismo? Stavo pensando di usare la funzione di tipo monad che restituirebbe {query, binding_names} ... – ProxyGear
Non credo che sarete in grado di ottenerlo senza modificare Ecto.Puoi dare la posizione, credo, come in 'def anonymous (q, pos), do: q |> dove ([am: pos], is_null (am.user_id))' ma questo è peggio IMO. –