Ecto order_by

In a case where there is default order_by :name :asc, if order_by :type :desc is given, does ecto automatically order them by type first and then name?

%Post{
name : A,
type: free
}

%Post{
name : B,
type: paid
}

%Post{
name : C,
type: free
}

%Post{
name : D,
type: paid
}

In this case, it returns in this order Post B, Post D, Post A, Post C. This is my expected result but I just want to know how this happens.

Thanks! :smiley:

Show us how you construct the Ecto query?

def list_posts(criteria \\ %{}) do
    {sort_by, sort_order} = sorters(criteria) || {:name, :asc}

    from(p in Post)
    |> order_by({^sort_order, ^sort_by})
    |>Repo.paginate(
      query,
      [
        before: Map.get(criteria, :before_cursor),
        after: Map.get(criteria, :after_cursor),
        cursor_fields: [{sort_by, sort_order}, :id],
        limit: Map.get(criteria, :limit, 10)
      ])
end

defp sorters(%{sort: %{sort_by: sort_by, sort_order: sort_order}}) do
    {sort_by, sort_order}
  end

I call the function like this Posts.list_posts(%{sort: %{sort_by: :type, sort_order: :desc}, limit: 2})

In this case, yes. However sorting by tuple is non-standard behaviour and instead you should provide list of fields instead, so it will be more SQL standard conformant.

Do you mind giving more clarity on how it is able to sort by both fields(type and name) when only type is given as sort_by?