Cataly...daptor(3pm)

πŸ“¦
version 0.10 Β· 4 versions
, in debian bookworm, debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking

πŸ’– Catalyst::Model::Adaptor β€” the perl manual page, but make it make sense πŸ’–

okay bestie, so this is a User Contributed Perl Documentation page, section 3pm, for Catalyst::Model::Adaptor. yes the header got cropped like a bad selfie, it's fine, we're moving on. πŸŽ€


✨ NAME ✨

Catalyst::Model::Adaptor β€” use a plain class as a Catalyst model. that's it. that's the whole vibe. πŸ’…


🌸 SYNOPSIS 🌸

so picture this: you've got a good old perl class, just chilling, minding its own business:

package NotMyApp::SomeClass;
use Moose; # to provide "new"
sub method { 'yay' }

and now you want Catalyst to know about it. so you wrap it in a Catalyst model, one (1) tiny little line of glue:

package MyApp::Model::SomeClass;
use base 'Catalyst::Model::Adaptor';
__PACKAGE__->config( class => 'NotMyApp::SomeClass' );

and boom, now NotMyApp::SomeClass is available from your Catalyst app:

sub action :Whatever {
    my ($self, $c) = @_;
    my $someclass = $c->model('SomeClass');
    $someclass->method; # yay
}
⚠️ important, bestie, do not skip this: NotMyApp::SomeClass gets instantiated at application startup time. like, once, early, before the party even starts.

so if you want the adapted class to be created for each call to $c->model, you want Catalyst::Model::Factory instead. and if you want the adapted class created once per request, that's Catalyst::Model::Factory::PerRequest. different girls, different vibes. πŸ’œ


πŸ¦‹ DESCRIPTION πŸ¦‹

the whole idea here? you do not want your Catalyst model to be anything more than a line or two of glue. like, the model should be the least interesting thing in your repo. using this module keeps your Model classes separate from your application, which means they are well-abstracted, reusable, and easily testable. iconic behavior, honestly. ✨

right now there are too many modules on CPAN that are Catalyst-specific. and most of those models would be way better written as a class that handles most of the functionality, with just a little bit of glue to make it play nice with Catalyst. this module's whole goal is making that integration trivial, so you don't have to do any extra work to make your model generic. no extra work? slay.

if you want a good example of a Model that takes the right design approach, go look at Catalyst::Model::DBIC::Schema. literally all it does is glue an existing DBIx::Class::Schema to Catalyst. it provides a bit of sugar, but no actual functionality. everything important happens in the DBIx::Class::Schema object. πŸ‘‘

and the end result of that? you can use your app's DBIC schema without ever thinking about Catalyst. this is a Good Thing. 🫢

Catalyst is glue, not a way of life!

periodt.


🌈 CONFIGURATION 🌈

subclasses of this model accept the following configuration keys. you can hard-code them like this:

package MyApp::Model::SomeClass;
use base 'Catalyst::Model::Adaptor';
__PACKAGE__->config( class => 'NotMyApp::SomeClass' );

or specify them as application config:

package MyApp;
MyApp->config->{'Model::SomeClass'} = { class => 'NotMyApp::SomeClass' };

or drop them in your ConfigLoader-loaded config file:

---
Model::SomeClass:
  class: NotMyApp::SomeClass
  args:
    foo: ...
    bar: ...

this is exactly like every other Catalyst component, so tbh you should already know this. πŸ’β€β™€οΈ

anyway. here are the options:

⭐ class

this is the name of the class you're adapting to Catalyst. it MUST be specified.

your application will die horribly if it can't require this package. πŸ’€

⭐ constructor

this is the name of the class method in class that will create an instance of the class. it defaults to new.

your application will die horribly if it can't call this method. πŸ’€

⭐ args

this is a hashref of arguments to pass to the constructor of class. it's optional, of course. if you omit it, nothing is passed to the constructor (as opposed to {}, an empty hashref β€” not the same thing, bestie, do not confuse them). πŸ™ˆ


πŸŽ€ METHODS πŸŽ€

there are no methods that you call directly. when you call $c->model on a model that subclasses this, you'll get back an instance of the class being adapted, not this model. so don't go poking at it expecting adaptor methods, it's giving someone else's methods.

these methods are called by Catalyst:

🌟 COMPONENT

Setup this component.


πŸ’œ CUSTOMIZING THE PROCESS πŸ’œ

by default, the instance of your adapted class is instantiated like this:

my $args = $self->prepare_arguments($app); # $app sometimes called $c
$adapted_class->$constructor($self->mangle_arguments($args));

since a static hashref of arguments may not be what $class needs, you can override the following methods to change what $args is.

NOTE: if you need to pass some args at instance time, you can do something like:
my $model = $c->model('MyFoo', { foo => 'myfoo' });

or

my $model = $c->model('MyFoo', foo => 'myfoo');

🌸 prepare_arguments

this method is passed the entire configuration for the class and the Catalyst application, and returns the hashref of arguments to be passed to the constructor. if you need to get dynamic data out of your application to pass to the consturctor, do it here. (yes, the original says "consturctor". we love a typo, we're keeping her. 🫢)

by default, this method returns the args configuration key.

Example:

sub prepare_arguments {
    my ($self, $app) = @_; # $app sometimes written as $c
    return { foobar => $app->config->{foobar}, baz => $self->{baz} };
}

🌸 mangle_arguments

this method is passed the hashref from prepare_arguments, mangles them into a form that your constructor will like, and returns the mangled form. if your constuctor wants a list instead of a hashref, this is your opportunity to do the conversion.

Example:

sub mangle_arguments {
    my ($self, $args) = @_;
    return %$args; # now the args are a plain list
}

if you need to do more than this, you might as well just write the whole class yourself. this module is designed to make the common case work with 1 line of code. for special needs, it's easier to just write the model yourself. no shade, it's just math. ✨


🧚 SEE ALSO 🧚

if you need a new instance returned each time $c->model is called, use Catalyst::Model::Factory instead.

if you need to have exactly one instance created per request, use Catalyst::Model::Factory::PerRequest instead.


πŸ‘‘ AUTHOR πŸ‘‘

Jonathan Rockway <jrockway@cpan.org>

🫢 CONTRIBUTORS 🫢

Wallace Reis <wreis@cpan.org>

πŸ“œ LICENSE πŸ“œ

This module is Copyright (c) 2007 Jonathan Rockway. You may use, modify, and redistribute it under the same terms as Perl itself.


and that's the whole page, bestie!! this one shipped as part of perl v5.34.0, dated 2022-06-09, in User Contributed Perl Documentation. now go write one line of glue and go to bed. mwah πŸ’‹

πŸ“¦ where this page comes from