egze
ContextKit - automatic CRUD operations in your context and more
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:
Most Liked
egze
It still calls the User.changeset function, so one way would be to not cast :is_admin in this changeset.
For the use-case when you do want to update the :is_admin field, you would need to create your own update_user_admin function.
This is how update_#{resource} function is generated context_kit/lib/context_kit/crud/scoped.ex at main · egze/context_kit · GitHub
FedericoAlcantara
egze
Released version 0.3.0
The main feature is the support of Phoenix 1.8 scopes.
Use the new ContextKit.CRUD.Scoped in your context.
defmodule MyApp.Blog do
use ContextKit.CRUD.Scoped,
repo: MyApp.Repo,
schema: MyApp.Blog.Comment,
queries: MyApp.Blog.CommentQueries,
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
Now, besides all the functions from before, you will get all functions with the scope as first argument.
# List all comments
MyApp.Blog.list_comments()
# List all comments belonging to current user
MyApp.Blog.list_comments(socket.assigns.current_scope)
Popular in Announcing
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance










