ContextKit is a modular toolkit for building robust Phoenix/Ecto contexts with standardized CRUD operations. It helps reduce boilerplate code while providing powerful querying capabilities and built-in pagination support.
Features
Automatic CRUD operation generation
Dynamic query building with extensive filtering options
Built-in pagination support
Flexible and extensible design
Custom query options for complex filtering
Description
I always end up customising the generated context functions via mix phx.gen...
. Typically I want to query records via the list_{resource}
function, paginate records and more. With ContextKit I generate all of that.
Examples
Letβs say, we have a schema MyApp.Accounts.User
. To get the auto-generated functions, you would need to add a small snippet to your context module:
defmodule MyApp.Accounts do use ContextKit.CRUD, repo: MyApp.Repo, schema: MyApp.Accounts.User, queries: __MODULE__ end
This generates some functions in your module, and you can do things like:
# List all users Accounts.list_users() # List with filters and pagination {users, pagination} = Accounts.list_users( status: "active", paginate: [page: 1, per_page: 20] ) # Get single user user = Accounts.get_user(123) user = Accounts.get_user!(123) # Raises if not found # Get one user by criteria user = Accounts.one_user(email: "user@example.com") # Create a new user MyApp.Accounts.create_user(%{email: "new@example.com"}) # Update a user MyApp.Accounts.update_user(user, %{email: "updated@example.com"}) # Get a changeset for updates MyApp.Accounts.change_user(user, %{email: "changed@example.com"}) # Delete user Accounts.delete_user(user) Accounts.delete_user(email: "user@example.com")
All the fields in the schema can be queried on automatically. There are many operators for advanced queries.
Accounts.list_users( filters: [ %{field: :email, op: :ilike, value: "@gmail.com"}, %{field: :status, op: :in, value: ["active", "pending"]}, %{field: :name, op: :like_or, value: ["john", "jane"]} ] )
Additionally you can define any custom query:
defmodule MyApp.Accounts do def apply_query_option({:with_active_posts, true}, query) do query |> join(:inner, [u], p in assoc(u, :posts)) |> where([_, p], p.status == "active") end end
and then you can do: MyApp.Accounts.list_users(with_active_posts: true)
You can also define query functions in a different module. Then just pass it instead of queries: __MODULE__
.
Links
- Hex.pm: https://hex.pm/packages/context_kit
- Hexdocs: https://hexdocs.pm/context_kit/ContextKit.html
- Github: