# ContextKit
[](https://github.com/egze/context_kit/actions/workflows/elixir.yml)
[](https://hex.pm/packages/context_kit)
[](https://hexdocs.pm/context_kit)
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.
## Installation
Add `context_kit` to your list of dependencies in `mix.exs`:
def deps do
[
{:context_kit, "~> 0.3.0"}
]
end
## Quick Start
### 1. Define Your Schema
Create your Ecto schemas defining the necessary fields.
```elixir
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
end
```
### 2. Integrate in Your Context
Use `ContextKit.CRUD.Scoped` or `ContextKit.CRUD` in your context module to hook up the schema, repository, and custom scoped queries.
- `ContextKit.CRUD.Scoped` will generate functions with and without scopes. (Requires `:pubsub` and `:scope` options).
- `ContextKit.CRUD` will generate functions only without scopes.
```elixir
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.
end
```
This 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.
## Additional Modules Overview
- **[ContextKit.CRUD](lib/context_kit/crud.ex)**
Provides standard CRUD operations and dynamic query building.
- **[ContextKit.CRUD.Scoped](lib/context_kit/crud/scoped.ex)**
Provides standard CRUD operations and dynamic query building with support of Phoenix scopes.
- **[ContextKit.Paginator](lib/context_kit/paginator.ex)**
Manages pagination including limit/offset calculations and metadata generation.
- **[ContextKit.Query](lib/context_kit/query.ex)**
Enables dynamic query building with extensive filtering options.
## Usage Examples
### Basic CRUD Operations
# 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)
### Advanced Filtering
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"]}
]
)
### Custom Query Options
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)
## Documentation
Full documentation is available at [https://hexdocs.pm/context_kit](https://hexdocs.pm/context_kit).
## Contributing
1. Fork the repository
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create a Pull Request
## License
MIT License. See LICENSE for details.