Trimming the result while composing ecto queries

I have this function/query.

  def verify_session_token_query(token) do
    query =
      from token in by_token_and_context_query(token, "session"),
        join: user in assoc(token, :user),
        where: token.inserted_at > ago(@session_validity_in_days, "day") and is_nil(token.killed_at),
        select: {user, token.needs_otp}

    {:ok, query}
  end

The query selects a tuple of a user struct and a boolean indicating if the user needs to provide a one time password.

I have wrapped it like so:

  def verify_session_token_with_otp_query(token) do
    {:ok, query} = verify_session_token_query(token)

    query = from token in query,
      where: token.needs_otp == false,
    # select: user

    {:ok, query}
  end

There is an additional condition in :where but I would also like to only :select the user (as opposed to the {user, flag} tuple). How do I do it? I have tried different bindings but always ended up with compile or runtime errors.

Side issue - the first function is generated by mix phx.gen.auth (and then tweaked). What could be the motivation for returning a tuple {:ok, query} rather than just query?

Koszal

This is actually explained well in the documentation:

If select is given more than once, an error is raised. Use exclude/2 if you would like to remove a previous select for overriding or see select_merge/3 for a limited version of select that is composable and can be called multiple times.

1 Like