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:
| function | action | item passed to Backpex.LiveResource.can?/3 |
|---|---|---|
insert/6 | :new | nil |
update/6 | :edit | the item |
update_all/5 | :edit | each item |
delete_all/4 | :delete | each 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 raisesArgumentErrorrather than being handed to a permissive catch-allcan?/3clause.:authorize?(boolean, defaulttrue) — set tofalseto 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
Broadcasts event on the live_resource topic in case result contains {:ok, item}.
Builds metadata passed to changeset functions.
TODO: move?
Parameters
assigns: The assigns that will be passed to the changeset function.target(optional, defaultnil): The target to be passed to the changeset function.
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: TheBackpex.LiveResourceto 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, defaultnil): The target to be passed to the changeset function.action(optional, default:validate): An atom indicating the action to be performed on the changeset.
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.
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 anidfield.assigns(map): The current assigns of the socket. Passed toBackpex.LiveResource.can?/3.live_resource(module): TheBackpex.LiveResourcemodule.opts(keyword list): A list of options::authorization_action(optional, default:delete): The action to authorize against.:authorize?(optional, defaulttrue): Set tofalseto skip authorization.
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): TheBackpex.LiveResourcemodule.
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.
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 thechangeset_function.fields(list): The fields for this insert.assigns(map): The current assigns of the socket. Passed toBackpex.LiveResource.can?/3and to the changeset function.live_resource(module): TheBackpex.LiveResourcemodule.opts(keyword list): A list of options::authorization_action(optional, default:new): The action to authorize against.:authorize?(optional, defaulttrue): Set tofalseto skip authorization.:after_save_fun(optional): A function called with the inserted item, returning{:ok, item}.- All remaining options are passed to
change/6.
Returns a list of items by given criteria.
Example criteria:
[ order: %{by: :item, direction: :asc}, pagination: %{page: 1, size: 5}, search: {"hello", [:title, :description]} ]
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): TheBackpex.LiveResourcemodule.
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 thechangeset_function.fields(list): The fields for this update.assigns(map): The current assigns of the socket. Passed toBackpex.LiveResource.can?/3and to the changeset function.live_resource(module): TheBackpex.LiveResourcemodule.opts(keyword list): A list of options::authorization_action(optional, default:edit): The action to authorize against.:authorize?(optional, defaulttrue): Set tofalseto skip authorization.:after_save_fun(optional): A function called with the updated item, returning{:ok, item}.- All remaining options are passed to
change/6.
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 Ectoupdate_allfunction.assigns(map): The current assigns of the socket. Passed toBackpex.LiveResource.can?/3.live_resource(module): TheBackpex.LiveResourcemodule.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, defaulttrue): Set tofalseto skip authorization.