2

ご挨拶、

私はCatalystを初めて使用し、ディスパッチロジックを実装しようとしています。

私のデータベースにはアイテムのテーブルがあり、それぞれに一意のurl_partフィールドがあり、すべてのアイテムには同じテーブルに親があり、ツリー構造になっています。bazの子がルートの子である場合、URLbarをこのオブジェクトにマップする必要があります。ツリーは任意の深さにすることができ、ユーザーはブランチまたはリーフに関係なく、任意のノードにアクセスできる必要があります。foo/foo/bar/baz

チェーンディスパッチャのドキュメントを調べてきましたが、これで自分が望むことができるかどうかわかりません。チェーンディスパッチャーの各ステップには属性の定義済みの名前が必要なようPathPartですが、URLはデータベース構造によってのみ決定されるようにしたいと思います。

これは既存のCatalystディスパッチャーで簡単に実装できますか、それとも独自のディスパッチクラスを作成する必要がありますか?

ありがとう!:)

ETA:

空のArgs属性を使用して、任意の数の引数をキャッチできることがわかりました。以下は、ルートの下のすべてのリクエストを正常にキャッチしているようです。

sub default :Path :Args() {
    my ( $self, $c ) = @_;

    my $path = $c->request->path;

    $c->response->status( 200 );
    $c->response->body( "Your path is $path" );
}

そこから手動でパスを解析して必要なものを取得できますが、これが私が求めていることを達成するための最良の方法であるかどうかはわかりません。

4

2 に答える 2

2

それはあなたのデータの構造に依存しますが、あなたの質問からは完全にはわかりません。

各レベルが特定の種類のものに対応する固定数のレベル(または少なくとも限られた範囲のレベル数)がある場合、Chainedはあなたが望むことを行うことができます-それは有効です(そしてまったく一般的です)パスにセグメント:CaptureArgs(1) PathPart('')を作成する連鎖アクション/*/。つまり、特定の固定文字列を表示することなく、パスの1つのセグメントを取得します。

そのようなものがない場合-たとえば、任意のツリーで無制限の数のレベルを追跡している場合、可変個引数:Argsアクションはおそらくまさにあなたが望むものであり、それを使用することに汚いものは何もありません。ただし、自分でデコードする必要はありません$c->req->path。残りのパスセグメントをから取得する$c->req->argsmy ($self, $c, @args) = @_;、アクションで実行することができます。新しいDispatchTypeを作成することはできますが、見返りの価値がない可能性があります。

于 2011-02-19T03:01:25.830 に答える
0

さまざまなオプションを試してみた結果、許容できる解決策に到達したと思います。残念ながら、再帰的なディスパッチを実行できませんでした:Chained(Catalystは、ハンドラーをそれ自体にチェーンしようとすると文句を言います。それは楽しいことではありません)。

だから私はこのように大きな、単一のハンドラーを使用することになりましたCaptureArgs

sub default : CaptureArgs(10) PathInfo('') { 
    my ( $self, $c, @args ) = @_;

    foreach my $i( 0 .. $#args ) { 
        my $sub_path = join '/', @args[ 0 .. $i ];

        if ( my $ent = $self->_lookup_entity( $c, $sub_path ) ) { 
            push @{ $c->stash->{ent_chain} }, $ent;
            next;
        }

        $c->detach( 'error_not_found' );
    }

    my $chain = join "\n", map { $_->entity_id } @{ $c->stash->{ent_chain} };
    $c->response->content_type( 'text/plain' );
    $c->response->body( $chain );
}

私がGETオンをすると/foo/bar/baz私は得る

foo
foo/bar
foo/bar/baz

それが私が欲しいものです。URLのいずれかの部分がDB内のオブジェクトに対応していない場合、404が返されます。

これは、10レベルの深さになることは決してない私のアプリケーションでは問題なく機能しますが、任意の深さのツリーをサポートできる、より一般的なソリューションを見つけられたらいいのにと思います。

于 2011-02-23T22:09:03.643 に答える