Day 8. Some notes on ACCEPT_CONTEXT, with and without antlers.
Today we'll show you how to avoid spaghetti controllers with ACCEPT_CONTEXT. It's tempting to stuff lots of business logic in your Controller, while usually this belongs in your Model. Although at first it seems like more effort to go to the trouble of setting up the model correctly, as your application grows, taking care of design like this rapidly pays dividends.
If you need access to a database schema or two in a model, or if you
need to be able to access path_to
or something else that belongs
in $c, you'll want to use this technique. First we'll show how to do
this without Moose, then with Moose.
Without Moose
Here's an example that gives us access to $c->path_to:
__PACKAGE__->mk_accessors(qw/path_to/); sub ACCEPT_CONTEXT { my ($self, $c ) = @_; $self = bless({ %$self, path_to => $c->path_to(''), }, ref($self)); return $self; }
Or if we wanted two different database schemas accessible from two different Catalyst::Models:
__PACKAGE__->mk_accessors(qw(schema1 schema2)); sub ACCEPT_CONTEXT { my ( $self, $c, @extra_arguments ) = @_; $self = bless({ %$self, schema1 => $c->model('My::Schema1')->schema, schema2 => $c->model('My::Schema2')->schema, }, ref($self)); return $self; }
Now when you have a subroutine in your model, you can access the relevant bit of $c with C$self->path_to, $self->schema1 or whatever you named your accessor. This avoids polluting your model with the bits of the context object that you don't need, makes your code more maintainable, and avoids some nasty gotchas that have to do with variable scope.
Doing the same with Moose
Catalyst 5.8 will use the Moose meta-object system, so it makes sense to use Moose to handle these issues for you.
The code is pretty similar:
use Moose; sub ACCEPT_CONTEXT { my ($self, $c ) = @_; my $new = $self->meta->clone_object($self, path_to => $c->path_to('')); return $new; }
The meta
method above is a benefit of Moose (actually
Class::MOP). Although this example isn't much clearer with Moose
than without, for the most part Moose greatly increases the read- and
write-ability of your code. See the Moose::Cookbook for many
examples.
AUTHORS
Kieren Diment <zarquon@cpan.org> Robert 'phaylon' Sedlacek <rs@474.at>