no need to set resultset_class with load_namespaces, and a couple other minor changes
[catagits/Catalyst-Manual.git] / lib / Catalyst / Manual / Tutorial / 03_MoreCatalystBasics.pod
index 38497af..3b95f04 100644 (file)
@@ -200,20 +200,22 @@ For our application, we want to add one new plugin into the mix.  To
 do this, edit C<lib/MyApp.pm> (this file is generally referred to as 
 your I<application class>) and delete the lines with:
 
-    use Catalyst qw/-Debug
-                    ConfigLoader
-                    Static::Simple/;
+    use Catalyst qw/
+        -Debug
+        ConfigLoader
+        Static::Simple
+    /;
 
 Then replace it with:
 
     # Load plugins
     use Catalyst qw/
-                    -Debug
-                    ConfigLoader
-                    Static::Simple
-                
-                    StackTrace
-                    /;
+        -Debug
+        ConfigLoader
+        Static::Simple
+    
+        StackTrace
+    /;
 
 B<Note:> Recent versions of C<Catalyst::Devel> have used a variety of 
 techniques to load these plugins/flags.  For example, you might see
@@ -233,7 +235,7 @@ browser, not in the console window from which you're running your
 application, which is where logging output usually goes.
 
 Make sure when adding new plugins you also include them as a new
-dependancy within the Makefile.PL file. For example, after adding
+dependency within the Makefile.PL file. For example, after adding
 the StackTrace plugin the Makefile.PL should include the following
 line:
 
@@ -306,7 +308,7 @@ and add the following method to the controller:
         # Set the TT template to use.  You will almost always want to do this
         # in your action methods (action methods respond to user input in
         # your controllers).
-        $c->stash->{template} = 'books/list.tt2';
+        $c->stash(template => 'books/list.tt2');
     }
 
 B<TIP>: See Appendix 1 for tips on removing the leading spaces when
@@ -560,11 +562,12 @@ tutorial.
 =head1 CREATE A SQLITE DATABASE
 
 In this step, we make a text file with the required SQL commands to
-create a database table and load some sample data.  We will use
-L<SQLite|http://www.sqlite.org>, a popular database that is
+create a database table and load some sample data.  We will use 
+SQLite (L<http://www.sqlite.org>), a popular database that is
 lightweight and easy to use. Be sure to get at least version 3. Open
 C<myapp01.sql> in your editor and enter:
 
+    PRAGMA foreign_keys = ON;
     --
     -- Create a very simple database to hold book and author information
     --
@@ -575,8 +578,8 @@ C<myapp01.sql> in your editor and enter:
     );
     -- 'book_author' is a many-to-many join table between books & authors
     CREATE TABLE book_author (
-            book_id     INTEGER,
-            author_id   INTEGER,
+            book_id     INTEGER REFERENCES book(id) ON DELETE CASCADE ON UPDATE CASCADE,
+            author_id   INTEGER REFERENCES author(id) ON DELETE CASCADE ON UPDATE CASCADE,
             PRIMARY KEY (book_id, author_id)
     );
     CREATE TABLE author (
@@ -648,14 +651,14 @@ required if you do a single SQL statement on the command line).  Use
 ".q" to exit from SQLite from the SQLite interactive mode and return to
 your OS command prompt.
 
-Please note that here we have chosen to use 'singular' table names. This
-is because the default inflection code for L<DBIx::Class:Schema::Loader>
-does NOT handle plurals. There has been much philosophical discussion
-on whether table names should be plural or singular. There is no one
-correct answer, as long as one makes a choice and remains consistent
-with it. If you prefer plural table names (e.g. they are easier and
-more natural to read) then you will need to pass it an inflect_map 
-option. See L<DBIx::Class:Schema::Loader> for more information.
+Please note that here we have chosen to use 'singular' table names. This is
+because the default inflection code for older versions of
+L<DBIx::Class::Schema::Loader> does NOT handle plurals. There has been much
+philosophical discussion on whether table names should be plural or singular.
+There is no one correct answer, as long as one makes a choice and remains
+consistent with it. If you prefer plural table names (e.g. you think that they
+are easier to read) then see the documentation in
+L<DBIx::Class::Schema::Loader::Base/naming> (version 0.05 or greater).
 
 For using other databases, such as PostgreSQL or MySQL, see 
 L<Appendix 2|Catalyst::Manual::Tutorial::10_Appendices>.
@@ -691,21 +694,23 @@ running this command:
 
     $ perl -MCatalyst::Model::DBIC::Schema -e \
         'print "$Catalyst::Model::DBIC::Schema::VERSION\n"'
-    0.23
+    0.31
 
 Please note the '\' above.  Depending on your environment, you might 
 be able to cut and paste the text as shown or need to remove the '\' 
 character to that the command is all on a single line.
 
-You should have version 0.23 or greater if you are following along 
+You should have version 0.31 or greater if you are following along 
 with Debian 5.  In other environments, you may need to run this 
 command to install it directly from CPAN:
 
     $ sudo cpan Catalyst::Model::DBIC::Schema
 
 And re-run the version print command to verify that you are now at 
-0.23 or higher.
+0.31 or higher.
 
+Please use version C<1.27> of L<DBD::SQLite> or later for proper foreign key
+support.
 
 =head2 Create Static DBIx::Class Schema Files
 
@@ -716,7 +721,8 @@ L<DBIx::Class::Schema::Loader|DBIx::Class::Schema::Loader> and
 automatically build the required files for us:
 
     $ script/myapp_create.pl model DB DBIC::Schema MyApp::Schema \
-        create=static dbi:SQLite:myapp.db
+        create=static dbi:SQLite:myapp.db \
+        on_connect_do="PRAGMA foreign_keys = ON"
      exists "/home/me/MyApp/script/../lib/MyApp/Model"
      exists "/home/me/MyApp/script/../t"
     Dumping manual schema for MyApp::Schema to directory /home/me/MyApp/script/../lib ...
@@ -755,11 +761,6 @@ into files.
 
 =item *
 
-C<components=TimeStamp> causes the help to include the 
-L<DBIx::Class::TimeStamp|DBIx::Class::TimeStamp> DBIC component.
-
-=item *
-
 And finally, C<dbi:SQLite:myapp.db> is the standard DBI connect string 
 for use with SQLite.
 
@@ -802,32 +803,15 @@ C<load_namspaces>.  For new applications, please try to use
 C<load_namespaces> since it more easily supports a very useful DBIC 
 technique called "ResultSet Classes."  If you need to convert an 
 existing application from "load_classes" to "load_namespaces," you can 
-use this process to automate the migration (but first make sure you 
-have v0.23 C<Catalyst::Model::DBIC::Schema> as discussed above):
+use this process to automate the migration, but first make sure you have
+version C<0.39> of L<Catalyst::Model::DBIC::Schema> and
+L<DBIx::Class::Schema::Loader> version C<0.05000> or later.
 
-    $ # First delete the existing schema file to disable "compatibility" mode
-    $ rm lib/MyApp/Schema.pm
-    $
-    $ # Then re-run the helper to build the files for "load_namespaces"
+    $ # Re-run the helper to upgrade for you
     $ script/myapp_create.pl model DB DBIC::Schema MyApp::Schema \
-        create=static dbi:SQLite:myapp.db
-    $
-    $ # Now convert the existing files over
-    $ cd lib/MyApp/Schema
-    $ perl -MIO::All -e 'for (@ARGV) { my $s < io($_); $s =~ s/.*\n\# You can replace.*?\n//s;
-          $s =~ s/'MyApp::Schema::/'MyApp::Schema::Result::/g; my $d < io("Result/$_");
-          $d =~ s/1;\n?//; "$d$s" > io("Result/$_"); }' *.pm
-    $ cd ../../..
-    $
-    $ # And finally delete the old files
-    $ rm lib/MyApp/Schema/*.pm
-
-The "C<perl -MIO::ALL ...>" script will copy all the customized 
-relationship (and other) information below "C<# DO NOT MODIFY>" line 
-from the old files in C<lib/MyApp/Schema> to the new files in 
-C<lib/MyApp/Schema/Result> (we will be starting to add some 
-"customized relationship information in the section below).
-
+        create=static naming=current use_namespaces=1 \
+        dbi:SQLite:myapp.db \
+        on_connect_do="PRAGMA foreign_keys = ON"
 
 =head1 ENABLE THE MODEL IN THE CONTROLLER
 
@@ -855,7 +839,7 @@ and delete the next 2 lines):
         # Set the TT template to use.  You will almost always want to do this
         # in your action methods (action methods respond to user input in
         # your controllers).
-        $c->stash->{template} = 'books/list.tt2';
+        $c->stash(template => 'books/list.tt2');
     }
 
 B<TIP>: You may see the C<$c-E<gt>model('DB::Book')> un-commented 
@@ -907,9 +891,9 @@ display something like:
     [debug] Statistics enabled
     [debug] Loaded plugins:
     .----------------------------------------------------------------------------.
-    | Catalyst::Plugin::ConfigLoader  0.22                                       |
-    | Catalyst::Plugin::StackTrace  0.09                                         |
-    | Catalyst::Plugin::Static::Simple  0.21                                     |
+    | Catalyst::Plugin::ConfigLoader  0.27                                       |
+    | Catalyst::Plugin::StackTrace  0.11                                         |
+    | Catalyst::Plugin::Static::Simple  0.25                                     |
     '----------------------------------------------------------------------------'
     
     [debug] Loaded dispatcher "Catalyst::Dispatcher"
@@ -950,7 +934,7 @@ display something like:
     | /books/list                         | /books/list                          |
     '-------------------------------------+--------------------------------------'
     
-    [info] MyApp powered by Catalyst 5.80003
+    [info] MyApp powered by Catalyst 5.80013
     You can connect to your server at http://debian:3000
 
 B<NOTE:> Be sure you run the C<script/myapp_server.pl> command from
@@ -1175,23 +1159,11 @@ template -- the wrapper will provide the overall feel of the page.
 =head2 Updating the Generated DBIx::Class Result Class Files
 
 Let's manually add some relationship information to the auto-generated 
-Result Class files. (Note: if you are using a database other than 
-SQLite, such as PostgreSQL, then the relationship could have been 
-automatically placed in the Result Class files.  If so, you can skip 
-this step.)  First edit C<lib/MyApp/Schema/Result/Book.pm> and add the 
+Result Class files. C<many_to_many> relationships are not currently
+automatically generated by L<DBIx::Class::Schema::Loader>.
+First edit C<lib/MyApp/Schema/Result/Book.pm> and add the 
 following text below the C<# You can replace this text...> comment:
 
-    #
-    # Set relationships:
-    #
-    
-    # has_many():
-    #   args:
-    #     1) Name of relationship, DBIC will create accessor with this name
-    #     2) Name of the model class referenced by this relationship
-    #     3) Column name in *foreign* table (aka, foreign key in peer table)
-    __PACKAGE__->has_many(book_authors => 'MyApp::Schema::Result::BookAuthor', 'book_id');
-    
     # many_to_many():
     #   args:
     #     1) Name of relationship, DBIC will create accessor with this name
@@ -1200,15 +1172,14 @@ following text below the C<# You can replace this text...> comment:
     #   You must already have the has_many() defined to use a many_to_many().
     __PACKAGE__->many_to_many(authors => 'book_authors', 'author');
 
-
 B<Note:> Be careful to put this code I<above> the C<1;> at the end of the
 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.
 
-This code defines both a C<has_many> and a C<many_to_many> 
-relationship. The C<many_to_many> relationship is optional, but it 
-makes it easier to map a book to its collection of authors.  Without 
+You'll notice there is already a C<has_many> relationship called
+C<book_authors>. The C<many_to_many> relationship is optional, but it makes it
+easier to map a book to its collection of authors.  Without 
 it, we would have to "walk" though the C<book_author> table as in 
 C<$book-E<gt>book_author-E<gt>first-E<gt>author-E<gt>last_name> (we 
 will see examples on how to use DBIx::Class objects in your code soon, 
@@ -1223,17 +1194,6 @@ Then edit C<lib/MyApp/Schema/Result/Author.pm> and add relationship
 information as follows (again, be careful to put in above the C<1;> but
 below the C<# DO NOT MODIFY THIS OR ANYTHING ABOVE!> comment):
 
-    #
-    # Set relationships:
-    #
-    
-    # has_many():
-    #   args:
-    #     1) Name of relationship, DBIC will create an accessor with this name
-    #     2) Name of the model class referenced by this relationship
-    #     3) Column name in *foreign* table (aka, foreign key in peer table)
-    __PACKAGE__->has_many(book_authors => 'MyApp::Schema::Result::BookAuthor', 'author_id');
-    
     # many_to_many():
     #   args:
     #     1) Name of relationship, DBIC will create accessor with this name
@@ -1242,28 +1202,6 @@ below the C<# DO NOT MODIFY THIS OR ANYTHING ABOVE!> comment):
     #   You must already have the has_many() defined to use a many_to_many().
     __PACKAGE__->many_to_many(books => 'book_authors', 'book');
 
-Finally, do the same for the "join table,"
-C<lib/MyApp/Schema/Result/BookAuthor.pm>:
-
-    #
-    # Set relationships:
-    #
-    
-    # belongs_to():
-    #   args:
-    #     1) Name of relationship, DBIC will create accessor with this name
-    #     2) Name of the model class referenced by this relationship
-    #     3) Column name in *this* table
-    __PACKAGE__->belongs_to(book => 'MyApp::Schema::Result::Book', 'book_id');
-    
-    # belongs_to():
-    #   args:
-    #     1) Name of relationship, DBIC will create accessor with this name
-    #     2) Name of the model class referenced by this relationship
-    #     3) Column name in *this* table
-    __PACKAGE__->belongs_to(author => 'MyApp::Schema::Result::Author', 'author_id');
-
-
 =head2 Run The Application
 
 Run the Catalyst development server script with the C<DBIC_TRACE> option
@@ -1492,7 +1430,7 @@ has changed):
         # Set the TT template to use.  You will almost always want to do this
         # in your action methods (actions methods respond to user input in
         # your controllers).
-        #$c->stash->{template} = 'books/list.tt2';
+        #$c->stash(template => 'books/list.tt2');
     }