custom-strategies
Custom strategies
ORM::Factory ships with four built-in strategies (build, create,
attributes-for, build-stubbed). You can register your own at runtime ā
or replace a built-in ā to integrate serialisation, alternative persistence
flows, or any other build pipeline.
Registering a strategy
A strategy is any class that does the ORM::Factory::Strategy role:
use ORM::Factory;
class JsonStrategy does ORM::Factory::Strategy {
method to-sym(--> Str) { 'json' }
method result(ORM::Factory::Evaluator $eval) {
my %h = $eval.attributes-hash(:skip-associations);
to-json(%h);
}
method association(Str:D $name, @variants, %overrides) {
ORM::Factory.build($name, |@variants, |%overrides);
}
}
ORM::Factory.register-strategy('json', JsonStrategy);Once registered, the strategy is dispatched by name via FALLBACK, so the
top-level helper is simply the name itself:
ORM::Factory.json('user'); # ā JSON for the user factory
ORM::Factory.json('user', 'admin', :name<Pat>); # variants + overrides flow throughInspecting the registry
ORM::Factory.strategies.keys; # registered names
ORM::Factory.strategy-class-for('json'); # the class
ORM::Factory.strategy-for('json'); # a fresh, persistence-wired instanceRe-registering a built-in
register-strategy accepts any built-in name, so a project can swap the
default build behaviour without monkey-patching:
class ShoutBuildStrategy does ORM::Factory::Strategy {
method to-sym(--> Str) { 'build' }
method result(ORM::Factory::Evaluator $eval) {
my $instance = $!persistence.instantiate($eval.factory.lookup-class, $eval.attributes-hash);
$instance.name = $instance.name.uc if $instance.^can('name');
$instance;
}
method association(Str:D $name, @variants, %overrides) {
ORM::Factory.build($name, |@variants, |%overrides);
}
}
ORM::Factory.register-strategy('build', ShoutBuildStrategy);
ORM::Factory.build('user').name; # ā uppercased
# Restore the default
ORM::Factory.register-strategy('build', ORM::Factory::BuildStrategy);Per-strategy association cascade
association is the cascade hook. A strategy controls how every implicit or
explicit association of the in-flight factory is built. For example, a
strategy that always stubs associations regardless of the top-level call:
class StubAssocStrategy does ORM::Factory::Strategy {
method to-sym(--> Str) { 'cascade-stub' }
method result(ORM::Factory::Evaluator $eval) {
$!persistence.instantiate($eval.factory.lookup-class, $eval.attributes-hash);
}
method association(Str:D $name, @variants, %overrides) {
ORM::Factory.build-stubbed($name, |@variants, |%overrides);
}
}
ORM::Factory.register-strategy('cascade-stub', StubAssocStrategy);
ORM::Factory.cascade-stub('article'); # article's author is stubbed