Извлечение Ecto-фрагмента в переменную - PullRequest
0 голосов
/ 05 апреля 2020

У меня есть фрагмент, который повторяется и довольно сложен. Я хотел бы извлечь его в переменную / функцию и использовать его несколько раз вместо того, чтобы писать его более одного раза. Вот один упрощенный пример, который я до сих пор пробовал среди множества разных подходов:

f = dynamic([u], fragment("order by name desc"))
query = from(u in User)
        |> order_by([u], ^f)
Repo.all(query)

Согласно документации это должно быть возможно при использовании dynamic, но я пытаюсь в order_by, select, having или что бы то ни было, я получаю сообщение об ошибке, похожее на:

(ArgumentError) expected a field as an atom, a list or keyword list in `order_by`, got: `dynamic([u], fragment("order by name desc"))`

Как мне этого добиться?


Обновление 1

Вот более реальный пример. Следующий код работает:

    from(p in Photo,
      join: pv in assoc(p, :v),
      left_join: pl in assoc(p, :l),
      left_join: pc in assoc(p, :c),
      select: %{p | last_activity_at: fragment("greatest(?, ?, ?)", max(p.inserted_at), max(pl.inserted_at), max(pc.inserted_at))},
      group_by: p.id,
      order_by: [desc: fragment("greatest(?, ?, ?)", max(p.inserted_at), max(pl.inserted_at), max(pc.inserted_at))]
    )

Однако я не могу заставить его работать, извлекая фрагмент или используя его с Dynami c или чем-то другим.

1 Ответ

0 голосов
/ 05 апреля 2020

В той же документации есть пример для order_by для Ecto.Query.dynamic/2

f = dynamic([u], fragment("order by name desc"))
# order_by = [desc: :name] # why not just this?
order_by = [desc: ^f]
query = from(u in User), order_by: ^order_by
Repo.all(query)

Для обновленного примера:

order = dynamic(
  [p, pl, pc], 
  fragment(
    "greatest(?, ?, ?)",
    max(p.inserted_at),
    max(pl.inserted_at),
    max(pc.inserted_at)
  )
)

from(
  p in Photo,
  join: pv in assoc(p, :v),
  left_join: pl in assoc(p, :l),
  left_join: pc in assoc(p, :c),
  select: ...,
  group_by: p.id,
  order_by: ^[desc: order]
)

Как указано в документации,

невозможно передать динамику за пределы root. Например, это не будет работать:

 from query, order_by: [asc: ^dynamic(...)]

Но это будет:

from query, order_by: ^[asc: dynamic(...)]
...