[Catalyst] Sanity Check -- requesting feedback on chaining
approach
Eden Cardim
edencardim at gmail.com
Wed Feb 16 04:28:21 GMT 2011
>>>>> "will" == will trillich <will.trillich at serensoft.com> writes:
will> Catalystas -- this chaining stuff is wicked awesome. We've
will> been following the below paradigm for the most part, and now
will> we want to expand a bit: package MyApp::Controller::Xyzzy;
will> sub base : Chained PathPart('xyzzy') CaptureArgs(0) { }
will> sub list : Chained('base') PathPart('') Args(0) { }
will> sub item : Chained('base') PathPart('') CaptureArgs(1) { }
will> sub view : Chained('item') PathPart('') Args(0) { }
will> The two new nodes we want to insert are for csv-download
will> (delivering all records) and paging (delivering a
will> subset). Here's what we're thinking:
will> package MyApp::Controller::Xyzzy;
will> sub base : Chained PathPart('xyzzy') CaptureArgs(0) { }
will> sub list : Chained('base') PathPart('') CaptureArgs(0) { }
will> sub page : Chained('list') PathPart('') Args(0) { }
will> sub csv : Chained('list') PathPart('csv') Args(0) { }
will> sub item : Chained('base') PathPart('') CaptureArgs(1) { }
will> sub view : Chained('item') PathPart('') Args(0) { }
will> Here the index view would come from page() instead of directly
will> from list(). csv() would download
will> resultset->search->({%params})->all whereas page() would
will> resultset-> search({%params},{page=>$p,rows=>$r}).
will> So any search parameters would be handled inside list() and
will> then paging parameters would be handled separately inside
will> page(). Right? Is there an elegant way to separate the two
will> sets of parameters?
Yes, this will work:
# in list()
$c->stash->{rs} =
$c->model('Foo')->search({%params});
# in page()
$c->stash->{paged_rs} =
$c->stash->{rs}->search({}, {page => $p, rows => $r});
...if that's what you're asking.
Other interesting things you can do:
sub add_item :Chained('list') PathPart('add') Args(0) {
my($self, $c) = @_;
$c->stash->{rs}->create({ %more_params })
}
sub related_items :Chained('list') PathPart('related') CaptureArgs(0) {
my($self, $c) = @_;
$c->stash->{rs} = $c->stash->{rs}->related_resultset('');
}
sub related_page :Chained('related_items') PathPart('page') Args(0) {
my($self, $c) = @_;
$c->forward('page');
}
sub related_csv :Chained('related_items') PathPart('csv') Args(0) {
my($self, $c) = @_;
$c->forward('csv');
}
Assuming %params in list() was a simple key/value map, add_items() is
going to use those, in addition to whatever's in %more_params, which is
cool because if you change the criteria in list(), it propagates
everywhere else as well. Plus, you reuse the page/csv implementation
easily. The combination of chained DBIC resultsets and catalyst chains
is very similar to curried functions (I believe that's what the initial
design goal was).
--
Eden Cardim
Software Engineer
Shadowcat Systems Ltd.
http://www.shadowcat.co.uk
http://blog.edencardim.com
More information about the Catalyst
mailing list