Skip to main content

Action

Trait Action 

Source
pub trait Action<R: Resource>: 'static {
    const NAME: &'static str;
    const ROW: bool = true;
    const BULK: bool = true;
    const CONFIRM: bool = false;

    // Required methods
    fn label(cx: &Cx) -> String;
    fn run(
        cx: &Cx,
        records: &[R::Model],
        ex: &mut dyn Executor,
    ) -> impl Future<Output = Result<()>> + Send;

    // Provided methods
    fn can_run(_cx: &Cx, _record: &R::Model) -> bool { ... }
    fn success(cx: &Cx, count: usize) -> String { ... }
}
Expand description

A mutation beyond create, update and delete: “publish”, “archive”, “resend the invite”.

An action runs on one record, from a button in its row, or on the selection, from the bulk bar, or both (ROW, BULK). ResourceDef::action declares it:

struct Publish;

impl Action<PostResource> for Publish {
    const NAME: &'static str = "publish";

    fn label(_cx: &Cx) -> String {
        "Publish".to_string()
    }

    fn can_run(_cx: &Cx, post: &Post) -> bool {
        post.status != "published"
    }

    async fn run(_cx: &Cx, posts: &[Post], ex: &mut dyn Executor) -> Result<()> {
        for post in posts {
            Post::filter(Post::fields().id().eq(post.id))
                .update()
                .status("published".to_string())
                .exec(&mut *ex)
                .await?;
        }
        Ok(())
    }
}

The framework owns everything around run, as it does for a delete:

  • the route, {list}/{key}/-/actions/{NAME} for a row and {list}/-/actions/{NAME} for the selection, and its CSRF check;
  • the transaction: the records are loaded through scoped_query inside it, run writes through the same executor, and an error rolls everything back;
  • the policy: every record must pass Ability::View, checked on the loaded rows before run;
  • the refusal: a row can_run refuses answers 403, and a bulk selection runs the records that pass it and reports the refused count as skipped. A selection that passes on none writes nothing and answers with an error notification;
  • Resource::after_commit with Mutation::Action once the transaction commits, and the success notification.

A row whose record fails can_run renders no button for the action, and a row that no bulk action and no delete allows renders no checkbox.

Required Associated Constants§

Source

const NAME: &'static str

The action’s URL segment, distinct among the resource’s actions.

ResourceDef::action refuses to compile a name that is not a single path segment: empty, . or .., or holding whitespace, a control character, a quote, a backslash or one of / ? # % & = { } ( ). RouterBuilderPanelExt::panel refuses a name that another action of the resource shares.

ⓘ
struct Archive;

impl Action<PostResource> for Archive {
    const NAME: &'static str = "archive/all";
}

let def = ResourceDef::<PostResource>::new().action::<Archive>();

Provided Associated Constants§

Source

const ROW: bool = true

Whether a row renders the action’s button. Defaults to true.

Source

const BULK: bool = true

Whether the bulk bar renders the action for the selection. Defaults to true.

Source

const CONFIRM: bool = false

Whether the action asks first through a confirmation dialog sharing the delete dialog’s mechanism and destructive wording. Defaults to false.

An unconfirmed POST answers 400.

Required Methods§

Source

fn label(cx: &Cx) -> String

The button text.

Source

fn run( cx: &Cx, records: &[R::Model], ex: &mut dyn Executor, ) -> impl Future<Output = Result<()>> + Send

Perform the action on records, the records of the row or selection that passed can_run, through the framework’s transaction ex.

Provided Methods§

Source

fn can_run(_cx: &Cx, _record: &R::Model) -> bool

Whether the action may run on record.

Source

fn success(cx: &Cx, count: usize) -> String

The success notification after a commit. Defaults to the label and the record count: "Publish: 3 records". A bulk run the action refused on some records appends their count out of the selection: "Publish: 3 records (2 of 5 skipped)".

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§