[Cascavel-pm] Catalyst: Dispatching
Ednardo Lobo
ednardo em lobo.eti.br
Sexta Maio 21 07:27:51 PDT 2010
Nilson Santos Figueiredo Jr. escreveu:
> 2010/5/20 Ednardo Lobo <ednardo em lobo.eti.br>:
>> 1) Class::DBI
>
> Primeira importante dica: troque o Class::DBI por DBIx::Class. É uma
> solução bem mais moderna, robusta e bem suportada pela comunidade.
Se o DBIx::Class é mais adequado ao Class::DBI, trocarei com prazer.
>> Minha maior dificuldade no momento é com relação ao mapeamento de URLs em
>> "actions" (dispatching), cuja a metodologia ainda não compreendi bem. Em
>> razão disso não sei ao certo qual a melhor forma de estruturar os
>> "Controllers" e as "actions" dentro deles.
>
> Esse conhecimento vem com o tempo.
> Você já leu as manpages adequadas, pelo que disse. Então o que falta
> mesmo é colocar a mão na massa.
Já estou com o Catalyst instalado e realizando testes. :-)
> Uma maneira fácil e que funciona bem (ao menos inicialmente) é tentar
> criar controllers para cada uma das entidades sobre as quais ocorrerão
> ações em seu sistema.
> Vamos supor que seu sistema tenha "Clientes" e "Pedidos de Compra".
> Então você teria um controller para cada um dos dois. Esses
> controllers, por sua vez, teriam ações como "create", "view",
> "update", "delete" (e ações adicionais que se mostrem necessárias).
Costumo organizar meu código mais ou menos da seguinte forma:
1) Package::MyApp::Cliente
Métodos globais para manipulação de clientes.
- get
Acessa o banco e obtém dados do cliente.
Usado em: Mod, Rmv e Prt
- valid
Valida dados que vão para o banco.
Usado em: Add, Mod, Rmv e Prt
2) Package::MyApp::Cliente::Lst
Lista, em páginas, todos os clientes.
3) Package::MyApp::Cliente::Add
Adiciona um cliente.
4) Package::Myapp::Cliente::Mod
Modifica cliente selecionado da lista.
5) Package::Myapp::Cliente::Rmv
Remove cliente selecionado da lista.
6) Package::Myapp::Cliente::Prt
Imprime/Mostra cliente selecionado da lista.
Todos esses métodos respondem à requisições e ao final geram um HTML que
é enxertado em outro (HTML base) através de Package::Myapp.
Pelo que venho estudando essa metologia vai de encontro com as técnicas
de engenharia usadas no Catalyst.
No caso do meu framework o fluxo de execução é da seguinte forma:
- Modificando cliente
URL: ?func=cliente&ope=mod&id=3
Execução: MyApp -> MyApp::Cliente -> MyApp::Cliente::Mod -> do(3)
Porém, no Catalyst, não consegui ainda compreender muito bem como seria
esse fluxo de execução que, no caso, é orquestrado pelo DISPATCHING. Mas
imagino que seria assim:
URL: /cliente/mod/3 ou /cliente/3/mod
Execução: MyApp::Cliente -> mod(3) ou MyApp::Cliente::Mod -> do(3)
DÚVIDAS:
1) Como enxertar o HTML da operação específica no HTML base?
2) Atribuir a View para, digamos, $c->stash->{enxerto} é o melhor caminho?
3) É possível executar isto de forma implícita, ou seja, se nada ao
contrário for dito o resultado do processamento da View vai direto para
$c->stash->{enxerto}.
> Como você já leu sobre o Chained, vou colocar abaixo um padrão que eu
> costumo usar, que acho bom. Basicamente, em cada um dos controllers,
> existirá uma ação "base" que serve como "âncora" para o controller,
> alé disso existirá uma ação "load" que carrega aquela entidade e as
> outras ações que precisam dela carregada serão encadeadas nesse ponto.
> De antemão já peço pra desculpar qualquer erro de sintaxe, pois estou
> escrevendo diretamente no email.
>
> package MyApp::Controller::PurchaseOrder;
>
> sub base : Chained ('.') CaptureArgs( 0 ) {
> # lógica que vai ser executada para cada ação nesse controller
> }
>
> sub load : Chained ('base') CaptureArgs(1) {
> my ($self, $c, $id) = @_;
> # carrega o elemento do banco de dados
> $c->stash->{purchase_order} =
> $c->model('Schema::PurchaseOrder')->find( $id );
> }
>
> sub view : Chained('load') Args(0) PathPart('') {
> # aqui o $c->stash->{purchase_order} já estará disponível
> }
>
> sub delete : Chained('load') Args(0) PathPart('delete') {
> my ($self, $c) = @_;
> $c->stash->{purchase_order}->delete;
> }
>
> sub create : Chained('base') Args(0) PathPart('create') {
> # essa é encadeada no 'base' então o purchase_order não está disponível
> }
>
> E aí, no seu controlador Root, coloca algo assim, para cada um dos
> controladores usando esse esquema:
>
> package MyApp::Controller::Root;
>
> sub purchaseorder : Chained('/') PathPart('purchaseorder') {}
Não compreendi a necessidade desta linha em ::Root?
> Dessa maneira, no final das contas você vai ter as seguintes URLs:
>
> /purchaseorder/123 -> view item 123
> /purchaseorder/123/delete -> delete item 123
> /purchaseorder/create -> create
>
> Existem módulos na CPAN que meio que automatizam essa tarefa de crirar
> aplicações em estruturas similares, mas como você está aprendendo,
> experimentar com o que eu postei acima pode ajudar.
Irei experimentar sim, mas poderia indicar um desses módulos?
Grato,
--
Ednardo Lobo
www.lobo.eti.br
Mais detalhes sobre a lista de discussão Cascavel-pm