calcinator v5.0.0 Calcinator.Controller View Source

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

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

Link to this section 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

Link to this section Functions

Link to this function get_subject(conn) View Source
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
Link to this function put_subject(conn, subject) View Source
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
Link to this function show_relationship(conn, params, calcinator) View Source

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
  # Route will be `/posts/:post_id/relationships/author`
  get "/relationships/author"",
      PostController,
      :show_relationship,
      as: :relationships_author,
      assigns: %{
        related: %{
          view_module: AuthorView
        }
        source: %{
          association: :author,
          id_key: "post_id"
        }
      }
end

For relationships, the related resource is not rendered through it’s view, but the related[:view_module] is still needed in the assigns for the view_module.type() of the associated resource since relatinships are composed of the "type" and "id" of the related resource(s).