NAME
Reaction::Manual::Example - Simple Reaction example
DESCRIPTION
This tutorial will guide you through the process of setting up and testing a very basic CRUD application based on the database from DBIx::Class::Manual::Example.
You need at least a fairly basic understanding of DBIx::Class::Schema for this example to have value for you.
Installation
Install 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 DBIx::Class::Manual::Example. Don't do any of the DBIx::Class related stuff, only the SQLite database.
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/;
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;
Reaction attributes
The rest
Reaction will use sub display_name for displaying when there is a 1:Many or Many:Many relation. It will return a suitable text representation.
Models
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;
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;
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;
%]
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
Notes
TODO
AUTHORS
See Reaction::Class for authors.
LICENSE
See Reaction::Class for the license.