diff options
Diffstat (limited to 'old/Manual/Example.pod')
-rw-r--r-- | old/Manual/Example.pod | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/old/Manual/Example.pod b/old/Manual/Example.pod new file mode 100644 index 0000000..02a55fe --- /dev/null +++ b/old/Manual/Example.pod @@ -0,0 +1,304 @@ +=head1 NAME + +Reaction::Manual::Example - Simple Reaction example + +=head1 DESCRIPTION + +This tutorial will guide you through the process of setting up and testing a +very basic CRUD application based on the database from +L<DBIx::Class::Manual::Example>. + +You need at least a fairly basic understanding of L<DBIx::Class::Schema> for +this example to have value for you. + +=head2 Installation + +Install L<DBIx::Class> via CPAN. + +Install Reaction from http://code2.0beta.co.uk/reaction/svn via SVN or SVK. + +Set up the database as mentioned in L<DBIx::Class::Manual::Example>. Don't do +any of the DBIx::Class related stuff, only the SQLite database. + +=head2 Create the application + + catalyst.pl Test::Reaction + cd Test-Reaction + script/test_reaction_create.pl Model Test::Reaction DBIC::Schema Test::Reaction::DB + +Also, remember to include Catalyst::Plugin::I18N in your plugin list, like +this: + + use Catalyst qw/-Debug ConfigLoader Static::Simple I18N/; + +=head2 Set up DBIx::Class::Schema + +In addition to the normal DBIC stuff, you need to moosify your DBIC classes. + +Change directory back from db to the directory app: + + cd lib/Test/Reaction + mkdir DB + +Then, create the following DBIx::Class::Schema classes: + +DB.pm: + + package Test::Reaction::DB; + + use base 'DBIx::Class::Schema'; + + __PACKAGE__->load_classes; + + 1; + +DB/Artist.pm: + + package Test::Reaction::DB::Artist; + + use base 'DBIx::Class'; + use Reaction::Class; + + has 'artistid' => ( isa => 'Int', is => 'ro', required => 1 ); + has 'name' => ( isa => 'NonEmptySimpleStr', is => 'rw', required => 1 ); + + sub display_name { + my $self = shift; + return $self->name; + } + + __PACKAGE__->load_components(qw/PK::Auto Core/); + __PACKAGE__->table('artist'); + __PACKAGE__->add_columns(qw/ artistid name /); + __PACKAGE__->set_primary_key('artistid'); + __PACKAGE__->has_many( 'cds' => 'Test::Reaction::DB::Cd' ); + + 1; + +DB/Cd.pm: + + package Test::Reaction::DB::Cd; + + use base 'DBIx::Class'; + use Reaction::Class; + + has 'cdid' => ( isa => 'Int', is => 'ro', required => 1 ); + has 'artist' => + ( isa => 'Test::Reaction::DB::Artist', is => 'rw', required => 1 ); + has 'title' => ( isa => 'NonEmptySimpleStr', is => 'rw', required => 1 ); + + sub display_name { + my $self = shift; + return $self->title; + } + + __PACKAGE__->load_components(qw/PK::Auto Core/); + __PACKAGE__->table('cd'); + __PACKAGE__->add_columns(qw/ cdid artist title/); + __PACKAGE__->set_primary_key('cdid'); + __PACKAGE__->belongs_to( 'artist' => 'Test::Reaction::DB::Artist' ); + __PACKAGE__->has_many( 'tracks' => 'Test::Reaction::DB::Track' ); + + 1; + +DB/Track.pm: + + package Test::Reaction::DB::Track; + + use base 'DBIx::Class'; + use Reaction::Class; + + has 'trackid' => ( isa => 'Int', is => 'ro', required => 1 ); + has 'cd' => ( isa => 'Test::Reaction::DB::Cd', is => 'rw', required => 1 ); + has 'title' => ( isa => 'NonEmptySimpleStr', is => 'rw', required => 1 ); + + __PACKAGE__->load_components(qw/PK::Auto Core/); + __PACKAGE__->table('track'); + __PACKAGE__->add_columns(qw/ trackid cd title/); + __PACKAGE__->set_primary_key('trackid'); + __PACKAGE__->belongs_to( 'cd' => 'Test::Reaction::DB::Cd' ); + + 1; + +=head3 Reaction attributes + +See L<Reaction::Types::Core> + +=head3 The rest + +Reaction will use I<sub display_name> for displaying when there is a 1:Many or +Many:Many relation. It will return a suitable text representation. + +=head2 Models + +=head3 Create Test::Reaction::Model::Action + +Still in lib/Test/Reaction, create + +Model/Action.pm: + + package Test::Reaction::Model::Action; + + use Reaction::Class; + + use Test::Reaction::DB; + + use aliased 'Reaction::InterfaceModel::Action::DBIC::ActionReflector'; + + my $r = ActionReflector->new; + + $r->reflect_actions_for( 'Test::Reaction::DB::Artist' => __PACKAGE__ ); + $r->reflect_actions_for( 'Test::Reaction::DB::Cd' => __PACKAGE__ ); + $r->reflect_actions_for( 'Test::Reaction::DB::Track' => __PACKAGE__ ); + + 1; + +=head2 Controllers + +Reaction controllers inherit from Reaction::UI::CRUDController, like this: + +Controller/Artist.pm + + package Test::Reaction::Controller::Artist; + + use strict; + use warnings; + use base 'Reaction::UI::CRUDController'; + use Reaction::Class; + + __PACKAGE__->config( + model_base => 'Test::Reaction', + model_name => 'Artist', + action => { base => { Chained => '/base', PathPart => 'artist' } } + ); + + 1; + +Controller/Cd.pm + + package Test::Reaction::Controller::Cd; + + use strict; + use warnings; + use base 'Reaction::UI::CRUDController'; + use Reaction::Class; + + __PACKAGE__->config( + model_base => 'Test::Reaction', + model_name => 'Cd', + action => { base => { Chained => '/base', PathPart => 'cd' } } + ); + + 1; + +Controller/Track.pm + + package Test::Reaction::Controller::Track; + + use strict; + use warnings; + use base 'Reaction::UI::CRUDController'; + use Reaction::Class; + + __PACKAGE__->config( + model_base => 'Test::Reaction', + model_name => 'Track', + action => { base => { Chained => '/base', PathPart => 'track' } } + ); + + 1; + +Finally, change Controller/Root.pm to + + package Test::Reaction::Controller::Root; + + use strict; + use warnings; + use base 'Reaction::UI::RootController'; + use Reaction::Class; + + use aliased 'Reaction::UI::ViewPort'; + use aliased 'Reaction::UI::ViewPort::ListView'; + use aliased 'Reaction::UI::ViewPort::ActionForm'; + + __PACKAGE__->config->{namespace} = ''; + + sub base :Chained('/') :PathPart('') :CaptureArgs(0) { + my ($self, $c) = @_; + + $self->push_viewport(ViewPort, layout => 'xhtml'); + } + + sub root :Chained('base') :PathPart('') :Args(0) { + my ($self, $c) = @_; + + $self->push_viewport(ViewPort, layout => 'index'); + } + + 1; + +=head2 View + +View/XHTML.pm looks like this + + package Test::Reaction::View::XHTML; + + use Reaction::Class; + + extends 'Reaction::UI::Renderer::XHTML'; + + 1; + +This is all the perly stuff. Now return to the base Test-Reaction directory and +create root/index: + + [% + + main_block = 'index'; + + BLOCK index; + + %]<p><a href="[% ctx.uri_for('/artist') %]">artist</a></p> + <p><a href="[% ctx.uri_for('/cd') %]">cd</a></p> + <p><a href="[% ctx.uri_for('/track') %]">track</a></p>[% + + END; + + %] + +=head2 Running + +Now all that remains is to tell catalyst about the root and the model. Let +test_reaction.yml look like this: + + --- + name: Test::Reaction + Controller::Root: + view_name: 'XHTML' + window_title: 'Reaction Test App' + Model::Test::Reaction: + schema_class: 'Test::Reaction::DB' + connect_info: + - 'dbi:SQLite:dbname=database/example.db' + +The finals step for this example is to link to Reaction's templates: + + ln -s <path to reaction install directory>/root/base/ root/base + +At last you're now ready to run the server + + script/test_reaction_server.pl + +=head1 Notes + +=head1 TODO + +=head1 AUTHORS + +See L<Reaction::Class> for authors. + +=head1 LICENSE + +See L<Reaction::Class> for the license. + +=cut |