Skip to content

Instantly share code, notes, and snippets.

@nwjlyons
Last active August 4, 2022 21:11
Show Gist options
  • Save nwjlyons/7e93c0882d830c6a15564372de121932 to your computer and use it in GitHub Desktop.
Save nwjlyons/7e93c0882d830c6a15564372de121932 to your computer and use it in GitHub Desktop.
Reusable Phoenix.LiveView
defmodule ListView do
@callback query(socket :: Phoenix.LiveView.Socket.t()) :: Ecto.Query.t()
defmacro __using__(opts \\ []) do
quote bind_quoted: [opts: opts] do
opts = Keyword.validate!(opts, [:repo, :schema, :per_page])
@repo Keyword.fetch!(opts, :repo)
@schema Keyword.get(opts, :schema)
@per_page Keyword.get(opts, :per_page, 10)
@behaviour ListView
use MyAppWeb, :live_view
import Ecto.Query
on_mount __MODULE__
def on_mount(:default, _params, _session, socket) do
{:cont, assign(socket, schema_list: schema_list(socket))}
end
def query(socket) do
Ecto.Query.from(@schema)
end
def schema_list(socket) do
socket
|> query()
|> Ecto.Query.limit(@per_page)
|> @repo.all()
end
def render(var!(assigns)) do
~H"""
<h1>Default render</h1>
<ul>
<%= for schema <- @schema_list do %>
<li><%= inspect schema %></li>
<% end %>
</ul>
"""
end
defoverridable ListView
defoverridable render: 1
end
end
end
@nwjlyons
Copy link
Author

nwjlyons commented Aug 4, 2022

defmodule MyAppWeb.UserLive.List do
  use ListView, repo: MyApp.Repo, schema: MyApp.Accounts.User, per_page: 2
end

@nwjlyons
Copy link
Author

nwjlyons commented Aug 4, 2022

defmodule MyAppWeb.UserLive.List do
  use ListView, repo: MyApp.Repo

  def query(socket) do
    Ecto.Query.from(u in MyApp.Accounts.User, where: u.is_active == true)
  end

  def render(assigns) do
    ~H"""
    <h1>override render <%= inspect @schema_list %></h1>
    """
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment