Catalyst::Manual::Tutorial::AdvancedCRUD - Catalyst Tutorial - Part 8: Advanced CRUD
-
-
=head1 OVERVIEW
This is B<Part 8 of 9> for the Catalyst tutorial.
=item 9
-L<Appendicies|Catalyst::Manual::Tutorial::Appendicies>
+L<Appendices|Catalyst::Manual::Tutorial::Appendices>
=back
-
-
=head1 DESCRIPTION
This part of the tutorial explores more advanced functionality for
In keeping with the Catalyst (and Perl) spirit of flexibility, there are
many different ways approach advanced CRUD operations in a Catalyst
environment. One alternative is to use
-L<Catalyst::Helper::Controller::Scaffold|Catalyst::Helper::Controller::Scaffold>
-to instantly construct a set of Controller methods and templates for
-basic CRUD operations. Although a popular subject in Quicktime movies
-that serve as promotional material for various frameworks, more
-real-world applications require more control. Other options include
-L<Data::FormValidator|Data::FormValidator> and
-L<HTML::FillInForm|HTML::FillInForm>.
-
-Here, we will make use of the L<HTML::Widget|HTML::Widget> to not only
-ease form creation, but to also provide validation of the submitted
-data. The approached used by the part of the tutorial is to slowly
-incorporate additional L<HTML::Widget|HTML::Widget> functionality in a
-step-wise fashion (we start with fairly simple form creation and then
-move on to more complex and "magical" features such as validation and
+L<Catalyst::Helper::Controller::Scaffold> to instantly construct a set
+of Controller methods and templates for basic CRUD operations. Although
+a popular subject in Quicktime movies that serve as promotional material
+for various frameworks, more real-world applications require more
+control. Other options include L<Data::FormValidator> and
+L<HTML::FillInForm>.
+
+Here, we will make use of the L<HTML::Widget> to not only ease form
+creation, but to also provide validation of the submitted data. The
+approached used by the part of the tutorial is to slowly incorporate
+additional L<HTML::Widget> functionality in a step-wise fashion (we
+start with fairly simple form creation and then move on to more complex
+and "magical" features such as validation and
auto-population/auto-saving).
-B<Note:> Part 8 of the tutorial is optional. Users who do not which to
+B<Note:> Part 8 of the tutorial is optional. Users who do not wish to
use L<HTML::Widget|HTML::Widget> may skip this section.
B<TIP>: Note that all of the code for this part of the tutorial can be
svn checkout http://dev.catalyst.perl.org/repos/Catalyst/trunk/examples/Tutorial@###
IMPORTANT: Does not work yet. Will be completed for final version.
-
-
=head1 C<HTML::WIDGET> FORM CREATION
-This section looks at how L<HTML::Widget|HTML::Widget> can be used to
+This section looks at how L<HTML::Widget> can be used to
add additional functionality to the manually created form from Part 3.
-
=head2 Add the C<HTML::Widget> Plugin
Open C<lib/MyApp.pm> in your editor and add the following to the list of
-plugins (be sure to leave the existing plugins enabled:
+plugins (be sure to leave the existing plugins enabled):
HTML::Widget
-
=head2 Add a Form Creation Helper Method
Open C<lib/MyApp/Controller/Books.pm> in your editor and add the
}
This method provides a central location (so it can be called by multiple
-actions, such as create and edit) that builds an HTML::Wiget-based form
-with the appropriate fields. The "Get Authors" code uses DBIC to
-retrieve a list of model objects and then uses C<map> to quickly create
-a hash where the hash keys are the database primary keys from the
-authors table and the associated values are the last names of the
-authors.
-
+actions, such as C<create> and C<edit>) that builds an HTML::Wiget-based
+form with the appropriate fields. The "Get Authors" code uses DBIC to
+retrieve a list of model objects and then uses C<map> to create a hash
+where the hash keys are the database primary keys from the authors table
+and the associated values are the last names of the authors.
=head2 Add Actions to Display and Save the Form
(e.g., C<hw_create_do> for a create operation but C<hw_update_do> to
update an existing book object).
-
=head2 Update the CSS
Edit C<root/src/ttsite.css> and add the following lines to the bottom of
messages in red. Note that we are pulling the color scheme settings
from the C<root/lib/config/col> file that was created by the TTSite
helper. This allows us to change the color used by various error styles
-in the CCS from a single location.
-
+in the CSS from a single location.
=head2 Create a Template Page To Display The Form
<p><a href="[% Catalyst.uri_for('list') %]">Return to book list</a></p>
-
=head2 Add Links for Create and Update via C<HTML::Widget>
Open C<root/src/books/list.tt2> in your editor and add the following to
<a href="[% Catalyst.uri_for('hw_update') %]">Update</a>
</p>
-
=head2 Test The <HTML::Widget> Create Form
Press C<Ctrl-C> to kill the previous server instance (if it's still
drop-down list, there are no restrictions on items such as the length of
the title (for example, you can create a one-letter title) and value for
the rating (you can use any number you want, and even non-numeric values
-with SQLite). The next section seeks to address this concern.
+with SQLite). The next section will address this concern.
B<Note:> Depending on the database you are using and how you established
the columns in your tables, the database could obviously provide various
the previous paragraph is that the I<web application> itself is not
performing any validation.
-
=head1 C<HTML::WIDGET> VALIDATION AND FILTERING
Although the use of L<HTML::Widget|HTML::Widget> in the previous section
extraneous whitespace from fields or to escape meta-characters in user
input.
-
=head2 Add Constraints and Filters to the Widget Creation Method
Open C<lib/MyApp/Controller/Books.pm> in your editor and update the
=back
-
=head2 Rebuild the Form Submission Method to Include Validation
Edit C<lib/MyApp/Controller/Books.pm> and change C<hw_create_do> to
=back
-
=head2 Try Out the Form
Press C<Ctrl-C> to kill the previous server instance (if it's still running) and restart it:
C<constraint> items will validate the logic and insert feedback as
appropriate.
-
=head1 Enable C<DBIx::Class::HTMLWidget> Support
In this section we will take advantage of some of the "auto-population"
In other words, the two methods are a mirror image of each other: one
reads from the database while the other writes to the database.
-
=head2 Add C<DBIx::Class::HTMLWidget> to DBIC Model
In order to use L<DBIx::Class::HTMLWidget|DBIx::Class::HTMLWidget>, we
__PACKAGE__->load_components(qw/PK::Auto Core HTMLWidget/);
-
=head2 Use C<populate_from_widget> in C<hw_create_do>
Edit C<lib/MyApp/Controller/Books.pm> and update C<hw_create_do> to
C<populate_from_widget> does not currently handle the relationships
between tables.
-
-
=head1 AUTHOR
Kennedy Clark, C<hkclark@gmail.com>
Copyright 2006, Kennedy Clark. All rights reserved.
-This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
Version: .94
Catalyst::Manual::Tutorial::Testing - Catalyst Tutorial - Part 7: Testing
-
-
=head1 OVERVIEW
This is B<Part 7 of 9> for the Catalyst tutorial.
=item 9
-L<Appendicies|Catalyst::Manual::Tutorial::Appendicies>
+L<Appendices|Catalyst::Manual::Tutorial::Appendices>
=back
-
-
=head1 DESCRIPTION
-
You may have noticed that the Catalyst Helper scripts automatically
-create C<.t> test scripts under the C<t> directory. This part of the
-tutorial briefly looks at how these tests can be used to not only ensure
-that your application is working correctly at the present time, but also
-provide automated regression testing as you upgrade various pieces of
-your application over time.
+create basic C<.t> test scripts under the C<t> directory. This part of
+the tutorial briefly looks at how these tests can be used to not only
+ensure that your application is working correctly at the present time,
+but also provide automated regression testing as you upgrade various
+pieces of your application over time.
B<TIP>: Note that all of the code for this part of the tutorial can be
pulled from the Catalyst Subversion repository in one step with the
IMPORTANT: Does not work yet. Will be completed for final version.
-
=head1 RUNNING THE "CANNED" CATALYST TESTS
There are a variety of ways to run Catalyst and Perl tests (for example,
plugin, it's generally easier to simply set the C<CATALYST_DEBUG=0>
environment variable. For example:
- CATALYST_DEBUG=0 prove --lib lib t
+ $ CATALYST_DEBUG=0 prove --lib lib t
During the C<t/02pod> and C<t/03podcoverage> tests, you might notice the
C<all skipped: set TEST_POD to enable this test> warning message. To
$ CATALYST_DEBUG=0 TEST_POD=1 prove --lib lib -v t
-
-
=head1 RUNNING A SINGLE TEST
You can also run a single script by appending its name to the C<prove>
$ CATALYST_DEBUG=0 perl -Ilib t/01app.t
-
=head1 ADDING YOUR OWN TEST SCRIPT
Although the Catalyst helper scripts provide a basic level of checks
"for free," testing can become significantly more helpful when you write
your own script to exercise the various parts of your application. The
-L<Test::WWW::Mechanize::Catalyst|Test::WWW::Mechanize::Catalyst> module
-is very popular for writing these sorts of test cases. This module
-extends L<Test::WWW::Mechanize|Test::WWW::Mechanize> (and therefore
-L<WWW::Mechanize|WWW::Mechanize>) to allow you to automate the action of
+L<Test::WWW::Mechanize::Catalyst> module is very popular for writing
+these sorts of test cases. This module extends L<Test::WWW::Mechanize>
+(and therefore L<WWW::Mechanize>) to allow you to automate the action of
a user "clicking around" inside your application. It gives you all the
benefits of testing on a live system without the messiness of having to
-use an actual web server.
+use an actual web server, and a real person to do the clicking.
To create a sample test case, open the C<t/live_app01.t> file in your
editor and enter the following:
use strict;
use warnings;
- # Load testing framework and use 'no_plan' to dynamically pick up all tests. Better
- # to replace "'no_plan'" with "tests => 30" so it knows exactly how many tests need
- # to be run (and will tell you if not), but 'no_plan' is nice for quick & dirty tests
+ # Load testing framework and use 'no_plan' to dynamically pick up
+ # all tests. Better to replace "'no_plan'" with "tests => 30" so it
+ # knows exactly how many tests need to be run (and will tell you if
+ # not), but 'no_plan' is nice for quick & dirty tests
+
use Test::More 'no_plan';
# Need to specify the name of your app as arg on next line
# Can also do:
# use Test::WWW::Mechanize::Catalyst "MyApp";
+
use ok "Test::WWW::Mechanize::Catalyst" => "MyApp";
-
-
+
# Create two 'user agents' to simulate two different users ('test01' & 'test02')
my $ua1 = Test::WWW::Mechanize::Catalyst->new;
my $ua2 = Test::WWW::Mechanize::Catalyst->new;
The C<live_app.t> test cases uses copious comments to explain each step
of the process. In addition to the techniques shown here, there are a
-variety of other methods available in
-L<Test::WWW::Mechanize::Catalyst|Test::WWW::Mechanize::Catalyst> (for
-example, regex-based matching). Consult the documentation for more
+variety of other methods available in L<Test::WWW::Mechanize::Catalyst>
+(for example, regex-based matching). Consult the documentation for more
detail.
B<TIP>: For I<unit tests> vs. the "full application tests" approach used
-by L<Test::WWW::Mechanize::Catalyst|Test::WWW::Mechanize::Catalyst>, see
-L<Catalyst::Test|Catalyst::Test>.
+by L<Test::WWW::Mechanize::Catalyst>, see L<Catalyst::Test>.
B<Note:> The test script does not test the C<form_create> and
C<form_create_do> actions. That is left as an exercise for the reader
Experiment with the C<DBIX_CLASS_STORAGE_DBI_DEBUG>, C<CATALYST_DEBUG>
and C<-v> settings. If you find that there are errors, use the
techniques discussed in the "Catalyst Debugging" section (Part 6) to
-isolate and fix the problem.
+isolate and fix any problems.
If you want to run the test case under the Perl interactive debugger,
try a command such as:
$ DBIX_CLASS_STORAGE_DBI_DEBUG=0 CATALYST_DEBUG=0 perl -d -Ilib t/live_app01.t
-Note that although the tutorial uses a single custom test case for
+Note that although this tutorial uses a single custom test case for
simplicity, you may wish to break your tests into different files for
better organization.
-
-
=head1 SUPPORTING BOTH PRODUCTION AND TEST DATABASES
You may wish to leverage the techniques discussed in this tutorial to
maintain both a "production database" for your live application and a
"testing database" for your test cases. One advantage to
-L<Test::WWW::Mechanize::Catalyst|Test::WWW::Mechanize::Catalyst> is that
+L<Test::WWW::Mechanize::Catalyst> is that
it runs your full application; however, this can complicate things when
you want to support multiple databases. One solution is to allow the
database specification to be overridden with an environment variable.
variable defined, it will default to the same C<dbi:SQLite:myapp.db> as
before.
-
-
=head1 AUTHOR
Kennedy Clark, C<hkclark@gmail.com>