Catalyst::Model::DBIC::Schemaのソース
http://search.cpan.org/src/BOGDAN/Catalyst-Model-DBIC-Schema-0.21/lib/Catalyst/Model/DBIC/Schema.pm
new の後半部分。Modelクラスを動的に増やして、そこに、ACCEPT_CONTEXTを生やしている。
sub new { my $self = shift->NEXT::new(@_); my $class = ref($self); my $model_name = $class; $model_name =~ s/^[\w:]+::(?:Model|M):://; # 略 no strict 'refs'; foreach my $moniker ($self->schema->sources) { my $classname = "${class}::$moniker"; *{"${classname}::ACCEPT_CONTEXT"} = sub { shift; shift->model($model_name)->resultset($moniker); } } return $self; }
ACCEPT_CONTEXT自体は、$c->model("Hoge", @args); と呼んだときに、
あれば使われるものだけども、このメソッドには、$cと@args がわたってくる。
Catalyst::Model::DBIC::Schemaでは、@argsを使うような使い方はしないわけだが、
これを利用してやる。
sub new { my $self = shift->NEXT::new(@_); # 略 no strict 'refs'; foreach my $moniker ($self->schema->sources) { my $classname = "${class}::$moniker"; *{"${classname}::ACCEPT_CONTEXT"} = sub { my ($self, $c, $method, @args) = @_; if (defined $method) { if ($method =~ s/^paged_//) { # ごにょごにょ return ...; } else { return $self->model($model_name)->resultset($moniker)->$method(@args) } } else { return $self->model($model_name)->resultset($moniker); } } } return $self; }
途中略しちゃってるけど、paged_ をメソッド名の先頭につけて、
my $rs = $c->model("Hoge", paged_search => {}, {});
とかすると、$rs は、ページ分けされたものが返ってきて、$c->stash->{pager} には、
$rs->pagerが突っ込み済みとか、そんなノリにしてやると、結構使えるんでないかと思います。
というか、ずいぶん楽です。
$c->req->param('page')はページ数だとか、まぁ、なんか、お約束を作っておく必要はあるけど。決めといたほうが良いし。