ContextKit is a modular toolkit for building robust Phoenix/Ecto contexts with standardized CRUD operations. It minimizes boilerplate while offering powerful querying, context scoping, and built-in pagination support.
Add context_kit to your list of dependencies in mix.exs:
def deps do
[
{:context_kit, "~> 0.5.0"}
]
end
Create your Ecto schemas defining the necessary fields.
defmodule MyApp.Schemas.User do
use Ecto.Schema
schema "users" do
field :email, :string
timestamps()
end
end
defmodule MyApp.Schemas.Comment do
use Ecto.Schema
schema "comments" do
field :text, :string
belongs_to :user, MyApp.Schemas.User
timestamps()
end
def changeset(comment, attrs, user_scope \\ nil) do
changeset =
comment
|> cast(attrs, [:text])
|> validate_required([:text])
|> assoc_constraint(:user)
if user_scope do
put_change(changeset, :user_id, user_scope.user.id)
else
changeset
end
end
endUse ContextKit.CRUD.Scoped or ContextKit.CRUD in your context module to hook up the schema, repository, and custom scoped queries.
ContextKit.CRUD.Scopedwill generate functions with and without scopes. (Requires:pubsuband:scopeoptions).ContextKit.CRUDwill generate functions only without scopes.
defmodule MyApp.Contexts.Comments do
use ContextKit.CRUD.Scoped,
repo: MyApp.Repo,
schema: MyApp.Schemas.Comment,
queries: __MODULE__,
pubsub: MyApp.PubSub, # For realtime notifications via PubSub.
scope: Application.compile_env(:my_app, :scopes)[:user] # To gain support for Phoenix 1.8 scopes.
endThis will automatically generate the list, get, create, update, delete, and more functions in your context module. Refer to the modules below for teh exact list.
-
ContextKit.CRUD Provides standard CRUD operations and dynamic query building.
-
ContextKit.CRUD.Scoped Provides standard CRUD operations and dynamic query building with support of Phoenix scopes.
-
ContextKit.Paginator Manages pagination including limit/offset calculations and metadata generation.
-
ContextKit.Query Enables dynamic query building with extensive filtering options.
# List all comments:
MyApp.Contexts.Comments.list_comments()
# List all comments using current scope:
MyApp.Contexts.Comments.list_comments(socket.assigns.current_scope)
# List comments with filtering and pagination:
{comments, paginator} = MyApp.Contexts.Comments.list_comments(
filters: [
%{field: :text, op: :like, value: "%interesting%"}
],
paginate: [page: 1, per_page: 10]
)
# Get a single comment (raises if not found):
comment = MyApp.Contexts.Comments.get_comment!(456)
# Create a new comment:
MyApp.Contexts.Comments.create_comment(%{text: "Great post!"})
# Update a comment:
MyApp.Contexts.Comments.update_comment(comment, %{text: "Updated comment content"})
# Delete a comment:
MyApp.Contexts.Comments.delete_comment(comment)
Utilize flexible filters with various operators:
MyApp.Contexts.Users.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"]}
]
)
Any option not recognized as a field filter or standard query option is passed to your custom queries module’s apply_query_option/2.
# Custom query option example for comments context
MyApp.Contexts.Comments.list_comments(with_recent_activity: true)
Full documentation is available at https://hexdocs.pm/context_kit.
- Fork the repository
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a Pull Request
MIT License. See LICENSE for details.