calcinator v2.4.0 Calcinator.Controller

Controller that replicates JSONAPI::ActsAsResourceController.

Actions

The available actions:

  • create
  • delete
  • get_related_resource
  • index
  • show
  • show_relationship
  • update

Chosen actions are specified to the use Calcinator.Controller call as a list of atoms:

use Calcinator.Controller,
    actions: ~w(create delete get_related_resource index show show_relationship update)a,
    ...

Authorization

Authenticated/Authorized Read/Write

If you authenticate users, you need to tell Calcinator.Controller they are your subject for the authorization_module

alias Calcinator.Controller

use Controller,
    actions: ~w(create delete get_related_resource index show show_relationship update)a,
    configuration: %Controller{
      authorization_module: MyApp.Authorization,
      ...
    }

# Plugs

plug :put_subject

# Functions

def put_subject(conn = %Conn{assigns: %{user: user}}, _), do: Controller.put_subject(conn, user)

Public Read-Only

If the controller exposes a read-only resource that you’re comfortable being publicly-readable, you can skip authorization: it will default to Calcinator.Authorization.Subjectless. Calcinator.Authorization.Subjectless will error out if you starts to have a non-nil subject, so it will catch if you’re mixing authenticated and unauthenticated pipelines accidentally.

alias Calcinator.Controller

use Controller,
    actions: ~w(get_related_resource index show show_relationship)a,
    configuration: %Controller{
      ...
    }

Routing

CRUD

If you only the standard CRUD actions

use Calcinator.Controller,
    actions: ~w(create delete index show update)a,
    ...

then the normal Phoenix resources macro will work

resources “/posts”, PostController

get_related_resource/3 and show_relationship/3

If you use the get_related_resource/3 or show_relationship/3 actions

use Calcinator.Controller,
    actions: ~w(get_related_resource index show show_relationship),
    ...

You’ll need custom routes

resources "/posts", PostController do
   get "/author",
       PostController,
       :get_related_resource,
       as: :author,
       assigns: %{
         related: %{
           view_module: AuthorView
         },
         source: %{
           association: :credential_source,
           id_key: "credential_id"
         }
       }
   get "/relationships/author"",
      PostController,
      :show_relationship,
      as: :relationships_author,
      assigns: %{
        association: :author,
        source: %{
          id_key: "author_id"
        }
      }
end

Summary

Functions

Unlike show, which can infer its information from the default routing information provided by Phoenix’s resources routing macro, get_related_resource/3 requires manual routing to setup the related and source assigns

Gets the subject used for the %Calcinator{} passed to action functions

Puts the subject used for the %Calciantor{} pass to action functions

Unlike show, which can infer its information from the default routing information provided by Phoenix’s resources routing macro, show_relationship/3 requires manual routing to setup the association and source assigns

Functions

create(conn, params, calcinator)
delete(conn, map, calcinator)
get_subject(conn)
get_subject(Plug.Conn.t) :: Authorization.subject

Gets the subject used for the %Calcinator{} passed to action functions.

iex> %Plug.Conn{} |>
iex> Calcinator.Controller.put_subject(:admin) |>
iex> Calcinator.Controller.get_subject()
:admin

It can be nil if put_subject/2 was not called or called put_subject(conn, nil).

iex> Calcinator.Controller.get_subject(%Plug.Conn{})
nil
iex> %Plug.Conn{} |>
iex> Calcinator.Controller.put_subject(nil) |>
iex> Calcinator.Controller.get_subject()
nil
index(conn, params, calcinator)
put_subject(conn, subject)
put_subject(Plug.Conn.t, Authorization.subject) :: Plug.Conn.t

Puts the subject used for the %Calciantor{} pass to action functions.

If you use subject-based authorization, where you don’t use Calcinator.Authorization.Subjectless (the default) for the :authorization module, then you will need to set the subject.

Here, the subject is set from the user assign set by some authorization plug (not shown)

defmodule MyAppWeb.PostController do
  alias Calcinator.Controller

  use Controller,
      actions: ~w(create destroy index show update)a,
      configuration: %Calcinator{
        authorization_module: MyAppWeb.Authorization,
        ecto_schema_module: MyApp.Post,
        resources_module: MyApp.Posts,
        view_module: MyAppWeb.PostView
      }

  # Plugs

  plug :put_subject

  # Functions

  def put_subject(conn = %Conn{assigns: %{user: user}}, _), do: Controller.put_subject(conn, user)
end
show(conn, map, calcinator)
show_relationship(conn, params, calcinator)

Unlike show, which can infer its information from the default routing information provided by Phoenix’s resources routing macro, show_relationship/3 requires manual routing to setup the association and source assigns.

resources "/posts", PostController do
  get "/relationships/author"",
      PostController,
      :show_relationship,
      as: :relationships_author,
      assigns: %{
        association: :author,
        source: %{
          id_key: "author_id"
        }
      }
end
update(conn, params, calcinator)