Backpex.Resource (Backpex v0.22.0)

Copy Markdown View Source

Generic context module for Backpex resources.

Work in progress

This module is still under heavy development and will change as we progress with the Backpex.Adapter implementation in the coming releases. Keep this in mind when using this module directly.

Authorization

All mutations in this module are authorized through Backpex.Authorization before anything else happens — before the changeset is built and before Backpex.Field.before_changeset/6 runs. An unauthorized call raises Backpex.ForbiddenError and never reaches the adapter.

Each mutation has a default authorization action:

functionactionitem passed to Backpex.LiveResource.can?/3
insert/6:newnil
update/6:editthe item
update_all/5:editeach item
delete_all/4:deleteeach item

Two options control this on every mutation:

  • :authorization_action (atom) — authorize against this action instead of the default. It must be a non-nil atom; anything else raises ArgumentError rather than being handed to a permissive catch-all can?/3 clause.
  • :authorize? (boolean, default true) — set to false to skip the check entirely. This is the escape hatch for system or cascade writes that are not a user-initiated action on that resource, for example nullifying foreign keys on another resource.

Both options are consumed here and never reach change/6.

For lists (update_all/5, delete_all/4) the check is strict: a single unauthorized item makes the whole call raise. A nil entry (a stale or forged item id) raises Backpex.NoResultsError. An empty list passes without calling the adapter's authorization.

Reads (list/4, get/4, get!/4, count/4) are not authorized here. :index and :show remain enforced in the view layer — filtering rows after pagination would corrupt counts and select-all.

Summary

Functions

Broadcasts event on the live_resource topic in case result contains {:ok, item}.

Builds metadata passed to changeset functions.

Applies a change to a given item by calling the specified changeset function. In addition, puts the given assocs into the function and calls the Backpex.Field.before_changeset/6 callback for each field.

Gets the total count of the current live_resource. Possibly being constrained the item query and the search- and filter options.

Deletes multiple items. Additionally broadcasts the corresponding event for each deleted item.

Gets a database record with the given fields by the given primary_value.

Same as get/4 but returns the result or raises an error.

Inserts a new item into a repository with specific parameters and options. It takes a repo module, a changeset function, an item, parameters for the changeset function, and additional options.

Returns a list of items by given criteria.

Re-reads a list of items from the data layer, keeping the order of the given list.

Handles the update of an existing item with specific parameters and options. It takes a repo module, a changeset function, an item, parameters for the changeset function, and additional options.

Updates multiple items from a given repository and schema. Additionally broadcasts the corresponding event, when PubSub config is given.

Functions

broadcast(result, event, live_resource)

Broadcasts event on the live_resource topic in case result contains {:ok, item}.

build_changeset_metadata(assigns, target \\ nil)

Builds metadata passed to changeset functions.

TODO: move?

Parameters

  • assigns: The assigns that will be passed to the changeset function.
  • target (optional, default nil): The target to be passed to the changeset function.

change(item, attrs, fields, assigns, live_resource, opts \\ [])

Applies a change to a given item by calling the specified changeset function. In addition, puts the given assocs into the function and calls the Backpex.Field.before_changeset/6 callback for each field.

Parameters

  • item: The initial data structure to be changed.
  • attrs: A map of attributes that will be used to modify the item. These attributes are passed to the changeset function.
  • fields: The fields for this change.
  • assigns: The assigns that will be passed to the changeset function.
  • live_resource: The Backpex.LiveResource to be used.
  • opts (keyword list): A list of options for customizing the behavior of the change function. The available options are:
    • assocs (optional, default []): A list of associations that should be put into the changeset.
    • target (optional, default nil): The target to be passed to the changeset function.
    • action (optional, default :validate): An atom indicating the action to be performed on the changeset.

count(criteria, fields, assigns, live_resource)

Gets the total count of the current live_resource. Possibly being constrained the item query and the search- and filter options.

delete_all(items, assigns, live_resource, opts \\ [])

Deletes multiple items. Additionally broadcasts the corresponding event for each deleted item.

Authorizes :delete for every item before touching the adapter. See the "Authorization" section in the module documentation.

Parameters

  • items (list): A list of structs, each representing an entity to be deleted. The list must contain items that have an id field.
  • assigns (map): The current assigns of the socket. Passed to Backpex.LiveResource.can?/3.
  • live_resource (module): The Backpex.LiveResource module.
  • opts (keyword list): A list of options:
    • :authorization_action (optional, default :delete): The action to authorize against.
    • :authorize? (optional, default true): Set to false to skip authorization.

get(primary_value, fields, assigns, live_resource)

Gets a database record with the given fields by the given primary_value.

Returns {:ok, nil} if no result was found.

Parameters

  • primary_value: The identifier for the specific item to be fetched.
  • assigns (map): The current assigns of the socket.
  • live_resource (module): The Backpex.LiveResource module.

get!(primary_value, fields, assigns, live_resource)

Same as get/4 but returns the result or raises an error.

insert(item, attrs, fields, assigns, live_resource, opts \\ [])

Inserts a new item into a repository with specific parameters and options. It takes a repo module, a changeset function, an item, parameters for the changeset function, and additional options.

Authorizes :new with a nil item before the changeset is built. See the "Authorization" section in the module documentation.

Parameters

  • item (struct): The Ecto schema struct.
  • attrs (map): A map of parameters that will be passed to the changeset_function.
  • fields (list): The fields for this insert.
  • assigns (map): The current assigns of the socket. Passed to Backpex.LiveResource.can?/3 and to the changeset function.
  • live_resource (module): The Backpex.LiveResource module.
  • opts (keyword list): A list of options:
    • :authorization_action (optional, default :new): The action to authorize against.
    • :authorize? (optional, default true): Set to false to skip authorization.
    • :after_save_fun (optional): A function called with the inserted item, returning {:ok, item}.
    • All remaining options are passed to change/6.

list(criteria, fields, assigns, live_resource)

Returns a list of items by given criteria.

Example criteria:

[ order: %{by: :item, direction: :asc}, pagination: %{page: 1, size: 5}, search: {"hello", [:title, :description]} ]

reload(items, fields, assigns, live_resource)

Re-reads a list of items from the data layer, keeping the order of the given list.

Each item is fetched by its primary value through get/4, so the LiveResource's item_query/3 applies. An item that no longer exists — or that has left the query's scope — comes back as nil instead of being dropped, which keeps the result positionally aligned with the input and lets Backpex.Authorization.authorize_all!/4 turn it into a Backpex.NoResultsError. A nil in the input stays nil.

This is what makes the item action execution gates authorize the current record rather than the snapshot that was cached when the row was selected. See Backpex.ItemAction.authorize_fresh!/3.

Like every other read in this module, this is not authorized.

Parameters

  • items (list): The items to re-read.
  • fields (list): The resource fields — they decide which associations are preloaded. Do not pass an item action's form fields here.
  • assigns (map): The current assigns of the socket.
  • live_resource (module): The Backpex.LiveResource module.

update(item, attrs, fields, assigns, live_resource, opts \\ [])

Handles the update of an existing item with specific parameters and options. It takes a repo module, a changeset function, an item, parameters for the changeset function, and additional options.

Authorizes :edit with the given item before the changeset is built. See the "Authorization" section in the module documentation.

Parameters

  • item (struct): The Ecto schema struct.
  • attrs (map): A map of parameters that will be passed to the changeset_function.
  • fields (list): The fields for this update.
  • assigns (map): The current assigns of the socket. Passed to Backpex.LiveResource.can?/3 and to the changeset function.
  • live_resource (module): The Backpex.LiveResource module.
  • opts (keyword list): A list of options:
    • :authorization_action (optional, default :edit): The action to authorize against.
    • :authorize? (optional, default true): Set to false to skip authorization.
    • :after_save_fun (optional): A function called with the updated item, returning {:ok, item}.
    • All remaining options are passed to change/6.

update_all(items, updates, assigns, live_resource, opts \\ [])

Updates multiple items from a given repository and schema. Additionally broadcasts the corresponding event, when PubSub config is given.

Authorizes :edit for every item before touching the adapter. See the "Authorization" section in the module documentation.

Parameters

  • items (list): A list of structs, each representing an entity to be updated.
  • updates (list): A list of updates passed to Ecto update_all function.
  • assigns (map): The current assigns of the socket. Passed to Backpex.LiveResource.can?/3.
  • live_resource (module): The Backpex.LiveResource module.
  • opts (keyword list): A list of options:
    • :event_name (optional, default "updated"): The name to be used when broadcasting the event.
    • :authorization_action (optional, default :edit): The action to authorize against.
    • :authorize? (optional, default true): Set to false to skip authorization.