How do I allow a single controller to display all messages or unread messages?

So I have a controller that looks like this:

defmodule AppChat.MessageController do
   use AppChat.Web, :controller

   def index(conn, params) do
      last_seen_id = params["last_seen_id"] || 0

      page =
        AppChat.Message
        |> where([m], m.id < ^last_seen_id)
        |> order_by([desc: :inserted_at, desc: :id])
        |> preload(:from_user)
        |> Repo.paginate()

      render(conn, "index.json", %{messages: page.entries, pagination: AppChat.PaginationHelpers.pagination(page)})
    end
 end

This will load all the messages based on a last_seen_id if one was provided.

What I also want to do is also have the ability to load only messages that have not been read. In my message table, I have a column called is_delivered and if it is set to false it means that the message has not been read and vice versa.

I was thinking of just creating a separate controller for it called unreadmessage controller but I want to know if this would be the right way to do it.

defmodule AppChat.MessageController do
   use AppChat.Web, :controller

   def index(conn, params) do
      ... load all messages
    end

    def index(conn, %{"to_id" => to_id}) do
      ... load only unread messages based on if the to_id == socket.id and if is_delivered is set to false
    end
 end

You’d want to flip these so the more specific is on top.

But otherwise just using a fallback of basically ‘all’ is generally what I do in these cases.

1 Like