=head1 NAME Catalyst::Manual::Tutorial::BasicCRUD - Catalyst Tutorial - Chapter 4: Basic CRUD =head1 OVERVIEW This is B for the Catalyst tutorial. L =over 4 =item 1 L =item 2 L =item 3 L =item 4 B =item 5 L =item 6 L =item 7 L =item 8 L =item 9 L =item 10 L =back =head1 DESCRIPTION This chapter of the tutorial builds on the fairly primitive application created in Chapter 3 to add basic support for Create, Read, Update, and Delete (CRUD) of C objects. Note that the 'list' function in Chapter 2 already implements the Read portion of CRUD (although Read normally refers to reading a single object; you could implement full read functionality using the techniques introduced below). This section will focus on the Create and Delete aspects of CRUD. More advanced capabilities, including full Update functionality, will be addressed in Chapter 9. Although this chapter of the tutorial will show you how to build CRUD functionality yourself, another option is to use a "CRUD builder" type of tool to automate the process. You get less control, but it's quick and easy. For example, see L, L, and L. You can checkout the source code for this example from the catalyst subversion repository as per the instructions in L. =head1 FORMLESS SUBMISSION Our initial attempt at object creation will utilize the "URL arguments" feature of Catalyst (we will employ the more common form- based submission in the sections that follow). =head2 Include a Create Action in the Books Controller Edit C and enter the following method: =head2 url_create Create a book with the supplied title, rating, and author =cut sub url_create : Local { # In addition to self & context, get the title, rating, & # author_id args from the URL. Note that Catalyst automatically # puts extra information after the "//model('DB::Books')->create({ title => $title, rating => $rating }); # Add a record to the join table for this book, mapping to # appropriate author $book->add_to_book_authors({author_id => $author_id}); # Note: Above is a shortcut for this: # $book->create_related('book_authors', {author_id => $author_id}); # Assign the Book object to the stash for display in the view $c->stash->{book} = $book; # This is a hack to disable XSUB processing in Data::Dumper # (it's used in the view). This is a work-around for a bug in # the interaction of some versions or Perl, Data::Dumper & DBIC. # You won't need this if you aren't using Data::Dumper (or if # you are running DBIC 0.06001 or greater), but adding it doesn't # hurt anything either. $Data::Dumper::Useperl = 1; # Set the TT template to use $c->stash->{template} = 'books/create_done.tt2'; } Notice that Catalyst takes "extra slash-separated information" from the URL and passes it as arguments in C<@_>. The C action then uses a simple call to the DBIC C method to add the requested information to the database (with a separate call to C to update the join table). As do virtually all controller methods (at least the ones that directly handle user input), it then sets the template that should handle this request. =head2 Include a Template for the 'url_create' Action: Edit C and then enter: [% # Use the TT Dumper plugin to Data::Dumper variables to the browser -%] [% # Not a good idea for production use, though. :-) 'Indent=1' is -%] [% # optional, but prevents "massive indenting" of deeply nested objects -%] [% USE Dumper(Indent=1) -%] [% # Set the page title. META can 'go back' and set values in templates -%] [% # that have been processed 'before' this template (here it's for -%] [% # root/lib/site/html and root/lib/site/header). Note that META on -%] [% # simple strings (e.g., no variable interpolation). -%] [% META title = 'Book Created' %] [% # Output information about the record that was added. First title. -%]

Added book '[% book.title %]' [% # Output the last name of the first author. This is complicated by an -%] [% # issue in TT 2.15 where blessed hash objects are not handled right. -%] [% # First, fetch 'book.authors' from the DB once. -%] [% authors = book.authors %] [% # Now use IF statements to test if 'authors.first' is "working". If so, -%] [% # we use it. Otherwise we use a hack that seems to keep TT 2.15 happy. -%] by '[% authors.first.last_name IF authors.first; authors.list.first.value.last_name IF ! authors.first %]' [% # Output the rating for the book that was added -%] with a rating of [% book.rating %].

[% # Provide a link back to the list page -%] [% # 'uri_for()' builds a full URI; e.g., 'http://localhost:3000/books/list' -%]

Return to list

[% # Try out the TT Dumper (for development only!) -%]
    Dump of the 'book' variable:
    [% Dumper.dump(book) %]
    
The TT C directive allows access to a variety of plugin modules (TT plugins, that is, not Catalyst plugins) to add extra functionality to the base TT capabilities. Here, the plugin allows L "pretty printing" of objects and variables. Other than that, the rest of the code should be familiar from the examples in Chapter 3. =head2 Try the 'url_create' Feature If the application is still running from before, use C to kill it. Then restart the server: $ DBIC_TRACE=1 script/myapp_server.pl Note that new path for C appears in the startup debug output. B: You can use C