The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.
Changes 016
META.yml 42
inc/Module/Install/AutoInstall.pm 19
inc/Module/Install/Base.pm 11
inc/Module/Install/Can.pm 11
inc/Module/Install/Fetch.pm 11
inc/Module/Install/Include.pm 11
inc/Module/Install/Makefile.pm 11
inc/Module/Install/Metadata.pm 45
inc/Module/Install/Win32.pm 11
inc/Module/Install/WriteAll.pm 11
inc/Module/Install.pm 48
lib/Catalyst/Manual/Cookbook.pod 417
lib/Catalyst/Manual/DevelopmentProcess.pod 1212
lib/Catalyst/Manual/ExtendingCatalyst.pod 11
lib/Catalyst/Manual/Intro.pod 11
lib/Catalyst/Manual/Tutorial/03_MoreCatalystBasics.pod 2354
lib/Catalyst/Manual/Tutorial/05_Authentication.pod 33
lib/Catalyst/Manual/Tutorial/09_AdvancedCRUD/09_FormHandler.pod 11
lib/Catalyst/Manual/Tutorial/10_Appendices.pod 3838
lib/Catalyst/Manual.pm 11
21 files changed (This is a version diff) 141165
@@ -1,5 +1,21 @@
 Revision history for Catalyst-Manual
 
+5.8008 2 Aug 2011
+    - Tutorial chaper 3
+      - Remove note about hacking tests to require MyApp so that MyApp->path_to
+        works. Application components should compile independently, and
+        therefore explain this and show configuring components from the
+        app class.
+
+    - Tutorial appendix
+      - Fix confusing mix of singular and plural table names in the MySQL
+        section to be plural, as per the rest of the tutorial.
+
+    - Cookbook
+      - Remove suggestion to generate RSS feeds using Template Toolkit.
+        This is a horrible idea, and it's very very easy to generate an
+        invalid feed.
+
 5.8007 29 Feb 2011
     - Tutorial
       - Switch to use of DBIx::Class::PassphraseColumn for hashed & salted
@@ -9,7 +9,7 @@ build_requires:
 configure_requires:
   ExtUtils::MakeMaker: 6.42
 distribution_type: module
-generated_by: 'Module::Install version 0.990'
+generated_by: 'Module::Install version 1.01'
 license: perl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -19,9 +19,7 @@ no_index:
   directory:
     - inc
     - t
-requires:
-  Test::More: 0
 resources:
   license: http://dev.perl.org/licenses/
   repository: http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Manual/5.80/trunk/
-version: 5.8007
+version: 5.8008
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.99';
+	$VERSION = '1.01';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
@@ -48,6 +48,14 @@ sub auto_install {
     while (my ($mod, $ver) = splice(@requires, 0, 2)) {
         $seen{$mod}{$ver}++;
     }
+    my @build_requires = map @$_, map @$_, grep ref, $self->build_requires;
+    while (my ($mod, $ver) = splice(@build_requires, 0, 2)) {
+        $seen{$mod}{$ver}++;
+    }
+    my @configure_requires = map @$_, map @$_, grep ref, $self->configure_requires;
+    while (my ($mod, $ver) = splice(@configure_requires, 0, 2)) {
+        $seen{$mod}{$ver}++;
+    }
 
     my @deduped;
     while (my ($mod, $ver) = splice(@features_require, 0, 2)) {
@@ -4,7 +4,7 @@ package Module::Install::Base;
 use strict 'vars';
 use vars qw{$VERSION};
 BEGIN {
-	$VERSION = '0.99';
+	$VERSION = '1.01';
 }
 
 # Suspend handler for "redefined" warnings
@@ -9,7 +9,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.99';
+	$VERSION = '1.01';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.99';
+	$VERSION = '1.01';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.99';
+	$VERSION = '1.01';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
@@ -8,7 +8,7 @@ use Fcntl qw/:flock :seek/;
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.99';
+	$VERSION = '1.01';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.99';
+	$VERSION = '1.01';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
@@ -515,6 +515,7 @@ sub __extract_license {
 		'GNU Free Documentation license'     => 'unrestricted', 1,
 		'GNU Affero General Public License'  => 'open_source',  1,
 		'(?:Free)?BSD license'               => 'bsd',          1,
+		'Artistic license 2\.0'              => 'artistic_2',   1,
 		'Artistic license'                   => 'artistic',     1,
 		'Apache (?:Software )?license'       => 'apache',       1,
 		'GPL'                                => 'gpl',          1,
@@ -550,9 +551,9 @@ sub license_from {
 
 sub _extract_bugtracker {
 	my @links   = $_[0] =~ m#L<(
-	 \Qhttp://rt.cpan.org/\E[^>]+|
-	 \Qhttp://github.com/\E[\w_]+/[\w_]+/issues|
-	 \Qhttp://code.google.com/p/\E[\w_\-]+/issues/list
+	 https?\Q://rt.cpan.org/\E[^>]+|
+	 https?\Q://github.com/\E[\w_]+/[\w_]+/issues|
+	 https?\Q://code.google.com/p/\E[\w_\-]+/issues/list
 	 )>#gx;
 	my %links;
 	@links{@links}=();
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.99';
+	$VERSION = '1.01';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.99';
+	$VERSION = '1.01';
 	@ISA     = qw{Module::Install::Base};
 	$ISCORE  = 1;
 }
@@ -31,7 +31,7 @@ BEGIN {
 	# This is not enforced yet, but will be some time in the next few
 	# releases once we can make sure it won't clash with custom
 	# Module::Install extensions.
-	$VERSION = '0.99';
+	$VERSION = '1.01';
 
 	# Storage for the pseudo-singleton
 	$MAIN    = undef;
@@ -230,8 +230,12 @@ sub preload {
 sub new {
 	my ($class, %args) = @_;
 
-    delete $INC{'FindBin.pm'};
-    require FindBin;
+	delete $INC{'FindBin.pm'};
+	{
+		# to suppress the redefine warning
+		local $SIG{__WARN__} = sub {};
+		require FindBin;
+	}
 
 	# ignore the prefix on extension modules built from top level.
 	my $base_path = Cwd::abs_path($FindBin::Bin);
@@ -463,4 +467,4 @@ sub _CLASS ($) {
 
 1;
 
-# Copyright 2008 - 2010 Adam Kennedy.
+# Copyright 2008 - 2011 Adam Kennedy.
@@ -572,7 +572,7 @@ root of your app (but not in any other controller).
 
 =head1 Models
 
-Models are where application data belongs.  Catalyst is exteremely
+Models are where application data belongs.  Catalyst is extremely
 flexible with the kind of models that it can use.  The recipes here
 are just the start.
 
@@ -961,47 +961,13 @@ L<http://search.cpan.org/perldoc?Template>
 =head2 Adding RSS feeds
 
 Adding RSS feeds to your Catalyst applications is simple. We'll see two
-different aproaches here, but the basic premise is that you forward to
+different approaches here, but the basic premise is that you forward to
 the normal view action first to get the objects, then handle the output
 differently.
 
-=head3 Using TT templates
-
-This is the aproach used in Agave (L<http://dev.rawmode.org/>).
-
-    sub rss : Local {
-        my ($self,$c) = @_;
-        $c->forward('view');
-        $c->stash->{template}='rss.tt';
-    }
-
-Then you need a template. Here's the one from Agave:
-
-    <?xml version="1.0" encoding="UTF-8"?>
-    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
-      <channel>
-	<title>[ [% blog.name || c.config.name || "Agave" %] ] RSS Feed</title>
-        <link>[% base %]</link>
-        <description>Recent posts</description>
-        <language>en-us</language>
-        <ttl>40</ttl>
-     [% WHILE (post = posts.next) %]
-      <item>
-        <title>[% post.title %]</title>
-        <description>[% post.formatted_teaser|html%]</description>
-        <pubDate>[% post.pub_date %]</pubDate>
-        <guid>[% post.full_uri %]</guid>
-        <link>[% post.full_uri %]</link>
-        <dc:creator>[% post.author.screenname %]</dc:creator>
-      </item>
-    [% END %]
-      </channel>
-    </rss>
-
 =head3 Using XML::Feed
 
-A more robust solution is to use L<XML::Feed>, as was done in the Catalyst
-Advent Calendar. Assuming we have a C<view> action that populates
+Assuming we have a C<view> action that populates
 'entries' with some DBIx::Class iterator, the code would look something
 like this:
 
@@ -1025,10 +991,10 @@ like this:
         $c->res->body( $feed->as_xml );
    }
 
-A little more code in the controller, but with this approach you're
+With this approach you're
 pretty sure to get something that validates.
 
-Note that for both of the above aproaches, you'll need to set the
+Note that for both of the above approaches, you'll need to set the
 content type like this:
 
     $c->res->content_type('application/rss+xml');
@@ -1369,7 +1335,7 @@ even though there are two different methods of looking up a track.
 
 This technique can be expanded as needed to fulfil your requirements - for example,
 if you inherit the first action of a chain from a base class, then mixing in a
-different base class can be used to duplicate an entire URL hieratchy at a different
+different base class can be used to duplicate an entire URL hierarchy at a different
 point within your application.
 
 =head2 Component-based Subrequests
@@ -1565,7 +1531,7 @@ the same Apache instance because the namespaces will collide.
 
 =head4 Cannot run different versions of libraries.
 
-If you have two differnet applications which run on the same machine,
+If you have two different applications which run on the same machine,
 which need two different versions of a library then the only way to do
 this is to have per-vhost perl interpreters (with different library paths).
 This is entirely possible, but nullifies all the memory sharing benefits that
@@ -17,7 +17,7 @@ or how best to go about their first CPAN extension module....
 
 =head2 Discussing proposed bugfixes or improvements
 
-L<http://dev.catalystframework.org/wiki/#Community> has information about how
+L<http://wiki.catalystframework.org/wiki/#Community> has information about how
 to get in touch with the Catalyst "community".  In particular, you would
 want to discuss a proposed change on the mailing list:
 
@@ -26,24 +26,24 @@ want to discuss a proposed change on the mailing list:
 or on IRC:
 
     irc://irc.perl.org/catalyst-dev
-    http://dev.catalystframework.org/wiki/livegroups
+    http://wiki.catalystframework.org/wiki/livegroups
 
 Usually, the core team will be more than happy for you to contribute, and
 will talk you through how to submit a patch, or get a "commit bit".
 
 =head2 Repositories
 
-The Catalyst subversion repository can be found at:
-
-    svn: http://dev.catalyst.perl.org/repos/Catalyst
-    browser: http://dev.catalyst.perl.org/svnweb/Catalyst
-
-and the git repository can be found at:
+The Catalyst git repository can be found at:
 
     read: git://git.shadowcat.co.uk/catagits/PROJECTNAME
     write: catagits@git.shadowcat.co.uk:PROJECTNAME
     browser: https://git.shadowcat.co.uk/gitweb/gitweb.cgi
 
+The Catalyst subversion repository can be found at:
+
+    svn: http://dev.catalyst.perl.org/repos/Catalyst
+    browser: http://dev.catalyst.perl.org/svnweb/Catalyst
+
 =head2 Schedule
 
 There is no dated release cycle for Catalyst. New releases will be made
@@ -53,12 +53,12 @@ significant feature addition, is completed.
 =head2 Roadmap for features
 
 The Catalyst Roadmap is kept at
-L<http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Runtime/5.80/trunk/lib/Roadmap.pod>
+L<http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits/Catalyst-Runtime.git;a=blob_plain;f=lib/Catalyst/ROADMAP.pod;hb=master>
 
 =head2 Bug list
 
 The TODO list with known bugs / deficiences is kept at
-L<http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Runtime/5.80/trunk/TODO>
+L<http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits/Catalyst-Runtime.git;a=blob_plain;f=TODO;hb=master>
 
 =head1 The Catalyst Core Team
 
@@ -121,9 +121,9 @@ current members.
 Any change to the Catalyst core which can not be conceived as a
 correction of an error in the current feature set will need to be
 accepted by at least 3 members of the Core Team before it can be
-committed to the trunk (which is the basis for CPAN releases). Anyone
+committed to master (which is the basis for CPAN releases). Anyone
 with access is at any time free to make a branch to develop a proof of
-concept for a feature to be committed to trunk.
+concept for a feature to be committed to master.
 
 =head2 Organizational and Philosophical Decisions.
 
@@ -127,7 +127,7 @@ for more information about roles in general.
 
 =head2 Inheritance and overriding methods
 
-When overriding a method, keep in mind that some day additionall
+When overriding a method, keep in mind that some day additional
 arguments may be provided to the method, if the last parameter is not
 a flat list. It is thus better to override a method by shifting the
 invocant off of C<@_> and assign the rest of the used arguments, so
@@ -104,7 +104,7 @@ example:
 
 Now http://localhost:3000/hello prints "Hello World!".
 
-Note that actions with the C< :Global > attribute are equivalent to
+Note that actions with the C< :Local > attribute are equivalent to
 using a C<:Path('action_name') > attribute, so our action could be
 equivalently:
 
@@ -145,7 +145,7 @@ The C<-d> option to C<script/myapp_server.pl>
 =item *
 
 The C<CATALYST_DEBUG=1> environment variable (or set it to
-zero to templorarily disable debug output).
+zero to temporarily disable debug output).
 
 =back
 
@@ -449,30 +449,61 @@ initially demonstrate the concepts, but quickly migrate to a more typical
 "wrapper page" type of configuration (where the "wrapper" controls the overall
 "look and feel" of your site from a single file or set of files).
 
-Edit C<lib/MyApp/View/HTML.pm> and you should see that the default
-contents contains something similar to the following:
+Edit C<lib/MyApp/View/HTML.pm> and you should see
+something similar to the following:
 
-    __PACKAGE__->config(TEMPLATE_EXTENSION => '.tt');
+    __PACKAGE__->config(
+        TEMPLATE_EXTENSION => '.tt',
+        render_die => 1,
+    );
 
 And update it to match:
 
     __PACKAGE__->config(
         # Change default TT extension
         TEMPLATE_EXTENSION => '.tt2',
-        # Set the location for TT files
-        INCLUDE_PATH => [
-                MyApp->path_to( 'root', 'src' ),
+        render_die => 1,
+    );
+
+This changes the default extension for Template Toolkit from '.tt' to
+'.tt2'.
+
+You can also configure components in your application class. For example,
+Edit C<lib/MyApp.pm> and you should see that the default:
+
+    __PACKAGE__->setup;
+
+Above this, add config:
+
+    __PACKAGE__->config(
+        'View::HTML' => {
+            #Set the location for TT files
+            INCLUDE_PATH => [
+                __PACKAGE__->path_to( 'root', 'src' ),
             ],
+        },
     );
+    # This line was here already
+    __PACKAGE__->setup;
 
-B<NOTE:> Make sure to add a comma after '.tt2' outside the single
-quote.
+This changes the base directory for your template files from
+C<root> to C<root/src>.
 
-This changes the default extension for Template Toolkit from '.tt' to 
-'.tt2' and changes the base directory for your template files from 
-C<root> to C<root/src>.  Stick with these conventions for the 
-tutorial, but feel free to use whatever options you desire in your 
-applications (as with most things Perl, there's more than one way to 
+The reason to do this outside the C<lib/MyApp/View/HTML.pm> file
+is that the template path is found with the C<path_to> method,
+to get a path relative to the application root (no matter where it
+is installed), but this requires the application to be loaded...
+
+Trying to set this setting in the view means that you have a chicken
+and egg problem, in that the view requires the application to be loaded,
+but loading the application loads the view.
+
+Putting the configuration which depends on the application class into
+that class is the neatest way to avoid this issue.
+
+Please stick with the settings above for the duration of the
+tutorial, but feel free to use whatever options you desire in your
+applications (as with most things Perl, there's more than one way to
 do it...).
 
 B<Note:> We will use C<root/src> as the base directory for our 
@@ -481,7 +512,6 @@ C<root/src/_controller_name_/_action_name_.tt2>.  Another popular option is to
 use C<root/> as the base (with a full filename pattern of 
 C<root/_controller_name_/_action_name_.tt2>).
 
-
 =head2 Create a TT Template Page
 
 First create a directory for book-related TT templates:
@@ -1021,7 +1051,7 @@ edit many individual files.
 In order to create a wrapper, you must first edit your TT view and
 tell it where to find your wrapper file. 
 
-Edit you TT view in C<lib/MyApp/View/HTML.pm> and change it to match the 
+Edit your TT view in C<lib/MyApp/View/HTML.pm> and change it to match the 
 following:
 
     __PACKAGE__->config(
@@ -1287,14 +1317,15 @@ L<DBIx::Class::Relationship/belongs_to> for the details.
 
 Although recent versions of SQLite and L<DBIx::Class::Schema::Loader> 
 automatically handle the C<has_many> and C<belongs_to> relationships, 
-C<many_to_many> relationships currently need to be manually inserted. 
-To add a C<many_to_many> relationship, first edit 
+C<many_to_many> relationship bridges (not technically a relationship)
+currently need to be manually inserted. 
+To add a C<many_to_many> relationship bridge, first edit 
 C<lib/MyApp/Schema/Result/Book.pm> and add the following text below 
 the C<# You can replace this text...> comment:
 
     # many_to_many():
     #   args:
-    #     1) Name of relationship, DBIC will create accessor with this name
+    #     1) Name of relationship bridge, DBIC will create accessor with this name
     #     2) Name of has_many() relationship this many_to_many() is shortcut for
     #     3) Name of belongs_to() relationship in model class of has_many() above
     #   You must already have the has_many() defined to use a many_to_many().
@@ -1305,7 +1336,7 @@ file.  As with any Perl package, we need to end the last line with
 a statement that evaluates to C<true>.  This is customarily done with
 C<1;> on a line by itself.
 
-The C<many_to_many> relationship is optional, but it makes it
+The C<many_to_many> relationship bridge is optional, but it makes it
 easier to map a book to its collection of authors.  Without 
 it, we would have to "walk" through the C<book_author> table as in 
 C<$book-E<gt>book_author-E<gt>first-E<gt>author-E<gt>last_name> (we 
@@ -1314,17 +1345,17 @@ but note that because C<$book-E<gt>book_author> can return multiple
 authors, we have to use C<first> to display a single author). 
 C<many_to_many> allows us to use the shorter 
 C<$book-E<gt>author-E<gt>first-E<gt>last_name>. Note that you cannot 
-define a C<many_to_many> relationship without also having the 
+define a C<many_to_many> relationship bridge without also having the 
 C<has_many> relationship in place.
 
 Then edit C<lib/MyApp/Schema/Result/Author.pm> and add the reverse 
-C<many_to_many> relationship for C<Author> as follows (again, be careful 
+C<many_to_many> relationship bridge for C<Author> as follows (again, be careful 
 to put in above the C<1;> but below the C<# DO NOT MODIFY THIS OR 
 ANYTHING ABOVE!> comment): 
 
     # many_to_many():
     #   args:
-    #     1) Name of relationship, DBIC will create accessor with this name
+    #     1) Name of relationship bridge, DBIC will create accessor with this name
     #     2) Name of has_many() relationship this many_to_many() is shortcut for
     #     3) Name of belongs_to() relationship in model class of has_many() above
     #   You must already have the has_many() defined to use a many_to_many().
@@ -846,14 +846,14 @@ C<__PACKAGE__-E<gt>config> setting to something like:
             name    => 'MyApp',
             # Disable deprecated behavior needed by old applications
             disable_component_resolution_regex_fallback => 1,
-            session => { flash_to_stash => 1 },
+            'Plugin::Session' => { flash_to_stash => 1 },
         );
 
 B<or> add the following to C<myapp.conf>:
 
-    <session>
+    <Plugin::Session>
         flash_to_stash   1
-    </session>
+    </Plugin::Session>
 
 The C<__PACKAGE__-E<gt>config> option is probably preferable here
 since it's not something you will want to change at runtime without it
@@ -92,7 +92,7 @@ add additional functionality to the manually created form from Chapter 4.
 
 =head2 Using FormHandler in your controllers 
 
-FormHandler dosen't have a Catalyst base controller, because interfacing
+FormHandler doesn't have a Catalyst base controller, because interfacing
 to a form is only a couple of lines of code.
 
 =head2 Create a Book Form
@@ -561,10 +561,10 @@ in you MySQL. You can simply figure out that your install supports it or not:
     # mysql -u root -p
     Enter password:
     Welcome to the MySQL monitor.  Commands end with ; or \g.
-    
+
     Type 'help;' or '\h' for help. Type '\c' to clear the current input 
     statement.
-    
+
     mysql> SHOW VARIABLES LIKE 'have_innodb';
     +---------------+-------+
     | Variable_name | Value |
@@ -572,7 +572,7 @@ in you MySQL. You can simply figure out that your install supports it or not:
     | have_innodb   | YES   |
     +---------------+-------+
     1 row in set (0.01 sec)
-    
+
     mysql> exit
     Bye
 
@@ -586,21 +586,21 @@ Create the database and set the permissions:
     # mysql -u root -p
     Enter password:
     Welcome to the MySQL monitor.  Commands end with ; or \g.
-    
+
     Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
-    
+
     mysql> CREATE DATABASE `myapp`;
     Query OK, 1 row affected (0.01 sec)
-    
+
     mysql> GRANT ALL PRIVILEGES ON myapp.* TO 'tutorial'@'localhost' IDENTIFIED BY 'yourpassword';
     Query OK, 0 rows affected (0.00 sec)
-    
+
     mysql> FLUSH PRIVILEGES;
     Query OK, 0 rows affected (0.00 sec)
-    
+
     mysql> exit
     Bye
-    
+
 
 =item *
 
@@ -615,20 +615,20 @@ Open the C<myapp01_mysql.sql> in your editor and enter:
     --
     -- Create a very simple database to hold book and author information
     --
-    CREATE TABLE IF NOT EXISTS `book` (
+    CREATE TABLE IF NOT EXISTS `books` (
       `id` int(11) NOT NULL AUTO_INCREMENT,
       `title` text CHARACTER SET utf8,
       `rating` int(11) DEFAULT NULL,
       PRIMARY KEY (`id`)
     ) ENGINE=InnoDB  DEFAULT CHARSET=utf8;
     -- 'book_authors' is a many-to-many join table between books & authors
-    CREATE TABLE IF NOT EXISTS `book_author` (
+    CREATE TABLE IF NOT EXISTS `book_authors` (
       `book_id` int(11) NOT NULL DEFAULT '0',
       `author_id` int(11) NOT NULL DEFAULT '0',
       PRIMARY KEY (`book_id`,`author_id`),
       KEY `author_id` (`author_id`)
     ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-    CREATE TABLE IF NOT EXISTS `author` (
+    CREATE TABLE IF NOT EXISTS `authors` (
       `id` int(11) NOT NULL AUTO_INCREMENT,
       `first_name` text CHARACTER SET utf8,
       `last_name` text CHARACTER SET utf8,
@@ -637,14 +637,14 @@ Open the C<myapp01_mysql.sql> in your editor and enter:
     ---
     --- Load some sample data
     ---
-    INSERT INTO `book` (`id`, `title`, `rating`) VALUES
+    INSERT INTO `books` (`id`, `title`, `rating`) VALUES
     (1, 'CCSP SNRS Exam Certification Guide', 5),
     (2, 'TCP/IP Illustrated, Volume 1', 5),
     (3, 'Internetworking with TCP/IP Vol.1', 4),
     (4, 'Perl Cookbook', 5),
     (5, 'Designing with Web Standards', 5);
-    
-    INSERT INTO `book_author` (`book_id`, `author_id`) VALUES
+
+    INSERT INTO `book_authors` (`book_id`, `author_id`) VALUES
     (1, 1),
     (1, 2),
     (1, 3),
@@ -653,8 +653,8 @@ Open the C<myapp01_mysql.sql> in your editor and enter:
     (4, 6),
     (4, 7),
     (5, 8);
-    
-    INSERT INTO `author` (`id`, `first_name`, `last_name`) VALUES
+
+    INSERT INTO `authors` (`id`, `first_name`, `last_name`) VALUES
     (1, 'Greg', 'Bastien'),
     (2, 'Sara', 'Nasseh'),
     (3, 'Christian', 'Degu'),
@@ -663,10 +663,10 @@ Open the C<myapp01_mysql.sql> in your editor and enter:
     (6, 'Tom', 'Christiansen'),
     (7, 'Nathan', 'Torkington'),
     (8, 'Jeffrey', 'Zeldman');
-    
-    ALTER TABLE `book_author`
-    ADD CONSTRAINT `book_author_ibfk_2` FOREIGN KEY (`author_id`) REFERENCES `author` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
-    ADD CONSTRAINT `book_author_ibfk_1` FOREIGN KEY (`book_id`) REFERENCES `book` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
+
+    ALTER TABLE `book_authors`
+    ADD CONSTRAINT `book_author_ibfk_2` FOREIGN KEY (`author_id`) REFERENCES `authors` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
+    ADD CONSTRAINT `book_author_ibfk_1` FOREIGN KEY (`book_id`) REFERENCES `books` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
 
 =item *
 
@@ -681,11 +681,11 @@ Make sure the data loaded correctly:
     $ mysql -u tutorial -p myapp
     Reading table information for completion of table and column names
     You can turn off this feature to get a quicker startup with -A
-    
+
     Welcome to the MySQL monitor.  Commands end with ; or \g.
-    
+
     Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
-    
+
     mysql> show tables;
     +-----------------+
     | Tables_in_myapp |
@@ -695,7 +695,7 @@ Make sure the data loaded correctly:
     | books           |
     +-----------------+
     3 rows in set (0.00 sec)
-    
+
     mysql> select * from books;
     +----+------------------------------------+--------+
     | id | title                              | rating |
@@ -707,7 +707,7 @@ Make sure the data loaded correctly:
     |  5 | Designing with Web Standards       |      5 |
     +----+------------------------------------+--------+
     5 rows in set (0.00 sec)
-    
+
     mysql>
 
 =back
@@ -750,12 +750,12 @@ Open C<myapp02_mysql.sql> in your editor and enter:
     --
     -- Add users and roles tables, along with a many-to-many join table
     --
-    CREATE TABLE IF NOT EXISTS `role` (
+    CREATE TABLE IF NOT EXISTS `roles` (
       `id` int(11) NOT NULL,
       `role` text CHARACTER SET utf8,
       PRIMARY KEY (`id`)
     ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-    CREATE TABLE IF NOT EXISTS `user` (
+    CREATE TABLE IF NOT EXISTS `users` (
       `id` int(11) NOT NULL,
       `username` text CHARACTER SET utf8,
       `password` text CHARACTER SET utf8,
@@ -765,7 +765,7 @@ Open C<myapp02_mysql.sql> in your editor and enter:
       `active` int(11) DEFAULT NULL,
       PRIMARY KEY (`id`)
     ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-    CREATE TABLE IF NOT EXISTS `user_role` (
+    CREATE TABLE IF NOT EXISTS `user_roles` (
       `user_id` int(11) NOT NULL DEFAULT '0',
       `role_id` int(11) NOT NULL DEFAULT '0',
       PRIMARY KEY (`user_id`,`role_id`),
@@ -774,24 +774,24 @@ Open C<myapp02_mysql.sql> in your editor and enter:
     --
     -- Load up some initial test data
     --
-    INSERT INTO `role` (`id`, `role`) VALUES
+    INSERT INTO `roles` (`id`, `role`) VALUES
     (1, 'user'),
     (2, 'admin');
-    
-    INSERT INTO `user` (`id`, `username`, `password`, `email_address`, `first_name`, `last_name`, `active`) VALUES
+
+    INSERT INTO `users` (`id`, `username`, `password`, `email_address`, `first_name`, `last_name`, `active`) VALUES
     (1, 'test01', 'mypass', 't01@na.com', 'Joe', 'Blow', 1),
     (2, 'test02', 'mypass', 't02@na.com', 'Jane', 'Doe', 1),
     (3, 'test03', 'mypass', 't03@na.com', 'No', 'Go', 0);
-    
-    INSERT INTO `user_role` (`user_id`, `role_id`) VALUES
+
+    INSERT INTO `user_roles` (`user_id`, `role_id`) VALUES
     (1, 1),
     (2, 1),
     (3, 1),
     (1, 2);
-    
-    ALTER TABLE `user_role`
-    ADD CONSTRAINT `user_role_ibfk_2` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
-    ADD CONSTRAINT `user_role_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
+
+    ALTER TABLE `user_roles
+    ADD CONSTRAINT `user_role_ibfk_2` FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
+    ADD CONSTRAINT `user_role_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
 
 =item *
 
@@ -6,7 +6,7 @@ package Catalyst::Manual;
 use strict;
 use warnings;
 
-our $VERSION = '5.8007';
+our $VERSION = '5.8008';
 
 =head1 NAME