I have this method
@spec modify_query(Ecto.Query.t) :: Ecto.Query.t
def modify_query(query) do
# modifies a Ecto.Query.t
end
Then I chain that method with a query:
Item
|> where([active: true])
|> order_by([desc: :start])
|> modify_query
The code works correctly but apparently for dialyzer
order_by
is not returning a Ecto.Query.t
because it complains with:
The call 'modify_query'... does not have a term of type atom() | 'Elixir.Ecto.Query':t() (with opaque subterms) as 1st argument
If I comment out # |> order_by([desc: :start])
then dialyzer
doesnt complain
I have tested through iex the output of:
Item
|> where([active: true])
|> order_by([desc: :start])
and it says it's data type is Ecto.Query:
Term
#Ecto.Query<from r in Item, where: r.active == true, order_by: [desc: r.start]>
Data type
Ecto.Query
So how can dialyzer complains??
More info here https://elixirforum.com/t/dialyxir-error-when-using-ecto-query-t-as-function-argument/7491
Basically, order_by is a macro and dialyxir complains about an opaque type.
I think it's fixed in recent versions of Ecto but if you have this issue in older versions of Ecto you can fix it by swapping the calls:
Item
|> order_by([desc: :start])
|> where([active: true])