2012-09-12 8 views
5

Ich lese den Abschnitt von Mojolicious::Guides::Growing, wo es Ihnen sagt, wie man ein Mojolicious :: Lite in eine "gut organisierte" cpan-uploadable Anwendung anbaut. Zuerst werden Sie aufgefordert, die M :: L-App in ein Startskript und eine Anwendungsklasse aufzuteilen.Warum Routing- und Controller-Aktionen in mojolicious trennen?

package MyApp; 
use Mojo::Base 'Mojolicious'; 

use MyUsers; 

sub startup { 
    my $self = shift; 

    # ...auth stuff omitted... 

    my $r = $self->routes; 
    $r->any('/' => sub { 
    my $self = shift; 

    my $user = $self->param('user') || ''; 
    my $pass = $self->param('pass') || ''; 
    return $self->render unless $self->users->check($user, $pass); 

    $self->session(user => $user); 
    $self->flash(message => 'Thanks for logging in.'); 
    $self->redirect_to('protected'); 
    } => 'index'); 

    $r->get('/protected' => sub { 
    my $self = shift; 
    return $self->redirect_to('index') unless $self->session('user'); 
    }); 

    $r->get('/logout' => sub { 
    my $self = shift; 
    $self->session(expires => 1); 
    $self->redirect_to('index'); 
    }); 
} 

1; 

Das macht für mich Sinn. Aber dann geht es weiter zu sagen, dass diese Anwendungsklasse kann weiter mit den Aktionen in eine Controller-Klasse überarbeitet werden, und die Anwendungsklasse selbst kann auf die Routing-Informationen reduziert werden:

package MyApp::Login; 
use Mojo::Base 'Mojolicious::Controller'; 

sub index { 
    my $self = shift; 

    my $user = $self->param('user') || ''; 
    my $pass = $self->param('pass') || ''; 
    return $self->render unless $self->users->check($user, $pass); 

    $self->session(user => $user); 
    $self->flash(message => 'Thanks for logging in.'); 
    $self->redirect_to('protected'); 
} 

sub protected { 
    my $self = shift; 
    return $self->redirect_to('index') unless $self->session('user'); 
} 

sub logout { 
    my $self = shift; 
    $self->session(expires => 1); 
    $self->redirect_to('index'); 
} 

1; 

package MyApp; 
use Mojo::Base 'Mojolicious'; 

use MyUsers; 

sub startup { 
    my $self = shift; 

    # ...auth stuff omitted... 

    my $r = $self->routes; 
    $r->any('/')->to('login#index')->name('index'); 
    $r->get('/protected')->to('login#protected')->name('protected'); 
    $r->get('/logout')->to('login#logout')->name('logout'); 
} 

1; 

Ich sehe nicht, warum dies ist besser als die "hybride" Version, in der Routen und Aktionen vermischt sind, denn jetzt, um zwischen den Aktionen mit redirect_to() im Controller umzuleiten, müssen Sie die Routing-Informationen in einer anderen Datei betrachten, und wenn Sie möchten Ändern Sie eine URL, Sie müssen es in zwei verschiedenen Dateien anstelle von einem tun. Dies:

$r->get('/protected' => sub { 
    my $self = shift; 
    return $self->redirect_to('index') unless $self->session('user'); 
    }); 

verwandelt sich in:

sub protected { 
    my $self = shift; 
    return $self->redirect_to('index') unless $self->session('user'); 
} 

$r->get('/protected')->to('login#protected')->name('protected'); 

die das Wort "geschützt" 4-mal in zwei verschiedenen Dateien hat (obwohl ich nicht sicher bin, was der Name ("geschützt") tut noch) .

Ich bin übrigens ein absoluter Neuling, wenn es um Web-Entwicklung geht.

Antwort

8

Es ist nicht überlegen; Es ist anders.

Sobald Sie über einen Entwickler hinausgehen, ist es nicht länger von Vorteil, Ihre App in einer Datei zu haben. Sie werden am Ende auf die Zehen treten. Selbst wenn Sie der einzige Entwickler sind, ist es nie einfach, Standorte in Dateien mit mehr als 1000 Zeilen zu verfolgen. Darüber hinaus ist es sehr nützlich, wenn Sie eine Datei ansehen und alle Ihre Routen auf einen Blick bestimmen können, wenn Sie mehr als nur ein paar Routen haben, ganz zu schweigen von 100+.

Außerdem müssen Sie die Weiterleitungs-URL in einer Controller-Aktion nicht ändern, wenn sich die Route ändert. Mojolicious übernimmt die Arbeit für Sie, wenn Sie benannte Routen nutzen.

+2

oohhhh, ich wusste nicht, dass redirect_to ('foo') interpretiert 'foo' als Name statt als Pfad '/ foo', und dass die M :: L Get/Post/any/etc Funktionen automatisch erstellte Namen. Es macht jetzt alles Sinn, danke. – user1481