Dependent Fields
A dependent field is a purely output field whose value changes whenever at least one field it
depends on is provided and accepted (e.g. username_last_updated_at should only update whenever
username changes).
- It must have either a default static value or a resolver for the default value.
- It must depend on at least one other field - lax, required,
virtual, or another dependent field (no circular dependencies). The parent
fields are declared with
.depends_on(...). - It must have a resolver to generate new values whenever a parent field is provided and accepted.
- It may use
readonlyto stop accepting further updates once its value differs from its default. - It may have
on_deleteandon_successevent handlers.
Example
value is a lax field with a default of 0. computed is a dependent field that equals
value + 1 (with its own fallback default of 1). The dependency on value is declared with
.depends_on(...):
use std::{future::ready, sync::LazyLock};
use ivo::{dependent_field, lax_field, IvoContext, IvoInputStruct, IvoModel, IvoStruct};
type Ctx = IvoContext<DataInput, Data>;
#[derive(Clone, Debug, PartialEq, IvoInputStruct)]
struct DataInput {
pub value: i32,
}
#[derive(Debug, Clone, PartialEq, IvoStruct)]
struct Data {
pub value: i32,
pub computed: i32,
}
static MODEL: LazyLock<IvoModel<DataInput, Data>> = LazyLock::new(|| {
IvoModel::new(
|f| {
f.field(lax_field("value").default(0)).field(
dependent_field("computed")
.default(1)
.depends_on(["value"])
.resolve(|ctx: Ctx, _| ready(ctx.values().value.unwrap_or(0) + 1)),
)
},
|o| o,
)
});