Упрощение нескольких запросов к одному Ecto

avatar
Junaid Farooq
8 августа 2021 в 19:31
38
0
0

У меня есть запрос, который работает совершенно нормально, но мне интересно, есть ли способ в экто объединить все в один запрос, этот вопрос больше касается более подробного ознакомления с возможностями того, как лучше использовать экто.

  def get_user_camera_ids(user) do
    from(
      camera in Camera,
      left_join: shares in assoc(camera, :shares),
      where: shares.user_id == ^user.id,
      or_where: camera.owner_id == ^user.id,
      select: [camera.id, shares.camera_id]
    )
    |> Repo.all()
    |> List.flatten()
    |> Enum.uniq()
    |> Enum.sort()
    |> Enum.reject(&is_nil/1)
  end

выше приведен список идентификаторов камер.

  def users(user) do
    cameras = Camera.get_user_camera_ids(user)

    compares =
      Compare
      |> join(:left, [comp], u in assoc(comp, :user))
      |> select([comp, u], %{name: fragment("concat(?  ' ', ?)", u.firstname, u.lastname), email: u.email})
      |> distinct(true)

    timelapses =
      Timelapse
      |> join(:left, [tls], u in assoc(tls, :user))
      |> select([tls, u], %{name: fragment("concat(?  ' ', ?)", u.firstname, u.lastname), email: u.email})
      |> distinct(true)

    Archive
    |> join(:left, [arc], u in assoc(arc, :user))
    |> select([arc, u], %{name: fragment("concat(?  ' ', ?)", u.firstname, u.lastname), email: u.email})
    |> distinct(true)
    |> union_all(^compares)
    |> union_all(^timelapses)
    |> where([arc], arc.camera_id in ^cameras)
    |> Repo.all()
  end

это дает список пользователей, что я хочу. Но возможно ли объединить все вышеперечисленные запросы в один? поскольку я вижу, что многие строки дублируются в join, select и distinct, любая помощь и предложения полезны, спасибо.

Источник

Ответы (0)