All Projects → rzane → contextual

rzane / contextual

Licence: other
🌈 Generate your Ecto contexts using this macro and eliminate boilerplate

Programming Languages

elixir
2628 projects

Projects that are alternatives of or similar to contextual

ecto generator
Generate Ecto schemas from existing database in Phoenix - Elixir
Stars: ✭ 20 (+11.11%)
Mutual labels:  phoenix, generate, ecto
Filterable
Filtering from incoming params in Elixir/Ecto/Phoenix with easy to use DSL.
Stars: ✭ 83 (+361.11%)
Mutual labels:  phoenix, ecto
Polymorphic embed
Polymorphic embeds in Ecto
Stars: ✭ 80 (+344.44%)
Mutual labels:  phoenix, ecto
Phoenix Ecto Encryption Example
🔐 A detailed example for how to encrypt data in a Phoenix (Elixir) App before inserting into a database using Ecto Types
Stars: ✭ 166 (+822.22%)
Mutual labels:  phoenix, ecto
Query
Query adds tools to aid the use of Ecto in web settings.
Stars: ✭ 23 (+27.78%)
Mutual labels:  phoenix, ecto
Wallaby
Concurrent browser tests with elixir
Stars: ✭ 1,143 (+6250%)
Mutual labels:  phoenix, ecto
Mipha
Proj Elixir Forum build with phoenix 1.5.
Stars: ✭ 153 (+750%)
Mutual labels:  phoenix, ecto
one plus n detector
Elixir library to help you detect 1+n queries in applications using Ecto
Stars: ✭ 20 (+11.11%)
Mutual labels:  phoenix, ecto
Params
Easy parameters validation/casting with Ecto.Schema, akin to Rails' strong parameters.
Stars: ✭ 239 (+1227.78%)
Mutual labels:  phoenix, ecto
query builder
Compose Ecto queries without effort
Stars: ✭ 56 (+211.11%)
Mutual labels:  phoenix, ecto
algoliax
Algolia integration to elixir application
Stars: ✭ 38 (+111.11%)
Mutual labels:  phoenix, ecto
Kaffy
Powerfully simple admin package for phoenix applications
Stars: ✭ 617 (+3327.78%)
Mutual labels:  phoenix, ecto
Paper trail
Track and record all the changes in your database with Ecto. Revert back to anytime in history.
Stars: ✭ 380 (+2011.11%)
Mutual labels:  phoenix, ecto
Ecto morph
morph your Ecto capabilities into the s t r a t o s p h e r e !
Stars: ✭ 72 (+300%)
Mutual labels:  phoenix, ecto
Machinery
State machine thin layer for structs (+ GUI for Phoenix apps)
Stars: ✭ 367 (+1938.89%)
Mutual labels:  phoenix, ecto
Phoenix live dashboard
Realtime dashboard with metrics, request logging, plus storage, OS and VM insights
Stars: ✭ 1,657 (+9105.56%)
Mutual labels:  phoenix, ecto
pretty print formatter
Pretty Print Formatter for Elixir Logger module -- Colorize Ecto's SQL ouput 🖌️
Stars: ✭ 22 (+22.22%)
Mutual labels:  phoenix, ecto
querie
Compose Ecto query from the client side
Stars: ✭ 20 (+11.11%)
Mutual labels:  phoenix, ecto
Formex
A better form library for Phoenix
Stars: ✭ 206 (+1044.44%)
Mutual labels:  phoenix, ecto
phoenix pagination
Simple pagination for Ecto and Phoenix that uses plain EEx templates.
Stars: ✭ 20 (+11.11%)
Mutual labels:  phoenix, ecto

Contextual Build Status

Contextual provides a macro that will generate your Ecto contexts for you.

Imagine you have a schema called MyApp.Posts.Post. Typically, you'd create a context to encapsulate Ecto access for creating, updating, and deleting posts.

You could use the built-in Phoenix generators to solve this problem, but then you're left with a bunch of boilerplate code that distracts the reader from the actual complexity in your contexts.

Instead, use Contextual and delete a bunch of boilerplate code. Or not, it's entirely your decision.

Installation

The package can be installed by adding contextual to your list of dependencies in mix.exs:

def deps do
  [{:contextual, "~> 1.0.0"}]
end

Documentation can be found at https://hexdocs.pm/contextual.

Usage

Contextual requires three options:

  • :name - A tuple of {:singular, :plural} naming for your resource.
  • :schema - An Ecto.Schema
  • :repo - An Ecto.Repo

Here's what your context might look like:

defmodule MyApp.Posts do
  use Contextual,
    name: {:post, :posts},
    schema: MyApp.Posts.Post,
    repo: MyApp.Repo
end

MyApp.Posts now has the following functions:

alias MyApp.Posts
alias MyApp.Posts.Post

import Ecto.Query

# List a collection
posts = Posts.list_posts()
posts = Posts.list_posts(from(p in Post, where: p.title == "Meatloaf"))

# Get a record by ID
post = Posts.get_post(19)
post = Posts.get_post!(19)
{:ok, post} = Posts.fetch_post(19)

# Get a record by attributes
post = Posts.get_post_by(title: "Meatloaf")
post = Posts.get_post_by!(title: "Meatloaf")
{:ok, post} = Posts.fetch_post_by(title: "Meatloaf")

# Create a changeset for a given post
changeset = Posts.change_post()
changeset = Posts.change_post(post)
changeset = Posts.change_post(%{title: "Meatloaf"})
changeset = Posts.change_post(post, %{title: "Meatloaf"})

# Create a post
{:ok, post} = Posts.create_post(%{title: "Meatloaf"})
post = Posts.create_post!(%{title: "Meatloaf"})

# Update a post
{:ok, post} = Posts.update_post(post, %{title: "Meatloaf"})
post = Posts.update_post!(post, %{title: "Meatloaf"})

# Delete a post
{:ok, post} = Posts.delete_post(post)
post = Posts.delete_post!(post)

Choosing which functions are generated

That seems reasonable. If you only wanted to define get_post, you can provide the :only option.

defmodule MyApp.Posts do
  use Contextual,
    name: {:post, :posts},
    schema: MyApp.Posts.Post,
    repo: MyApp.Repo,
    only: [:get]
end

Similarly, Contextual provides an :except option, which is basically just the opposite of :only.

Customizing function names

Contextual allows you to choose how your functions are named by using a name generator.

First, create a module that will serve as a name generator:

defmodule MyApp.ContextNaming do
  def generate_name(:list, {_singular, plural}) do
    :"all_#{plural}"
  end

  def generate_name(:get, {singular, _plural}) do
    :"find_#{singular}"
  end

  def generate_name(_, _), do: :default
end

The generate_name/2 function must return an atom. If the function returns :default, Contextual will fallback to the default naming convention.

Next, you'll need to configure your context to use your name generator:

defmodule MyApp.Posts do
  use Contextual,
    name: {:post, :posts},
    schema: MyApp.Posts.Post,
    repo: MyApp.Repo,
    name_generator: {MyApp.ContextNaming, :generate_name}
end

Now, you'll have all_posts instead of list_posts and find_post instead of get_post.

Typespecs

Contextual will automatically generate documentation and typespecs for thefunctions that it defines. However, it expects your schema to have a type t defined.

To get the typespecs working properly, you'll need to define that type on your schema:

defmodule MyApp.Posts.Post do
  # ...
  @type t :: %__MODULE__{}
end

Contributing

The tests run against PostgreSQL. The test command will setup a test database for you.

To run the tests, just run:

$ mix test
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].