Date: 2007-12-05 02:10:56 +0000 (Wed, 05 Dec 2007)
New Revision: 7229
day 10 ready
--- trunk/examples/CatalystAdvent/root/2007/pen/10.pod 2007-12-04 21:46:14 UTC (rev 7228)
+++ trunk/examples/CatalystAdvent/root/2007/pen/10.pod 2007-12-05 02:10:56 UTC (rev 7229)
@@ -1,5 +1,201 @@
=head1 Day 10 - Rapid CRUD with Catalyst
+Today we'll build an entire CRUD application with 20
+lines of Perl, using L<CatalystX::CRUD>, L<Rose::HTML::Objects>,
+Many of the other Advent Calendar entries this year will focus on
+similar technologies used in much more glamorous ways. This entry
+is down-and-dirty form-based CRUD. You know, the kind that likely
+still pays your bills.
+Catalyst has its origins in Maypole, which was a CRUD-oriented
+web application framework. See
+L<http://www.perl.com/pub/a/2004/04/15/maypole.html> for example. While
+Catalyst is much more flexible now and not tied to CRUD in particular,
+CRUD remains one of the most frequently implemented features. And now,
+it can be one of the easiest to implement as well.
+=head2 Impatient? Here's the code.
+We need a L<Rose::DB> subclass to manage the database connections.
+For this tutorial we'll create a test database with SQLite called
+Read the L<Rose::DB::Tutorial> documentation when you get to the point
+of connecting to your existing database(s).
+Create a subclass of Rose::DB called MyDB.pm:
+ package MyDB;
+ use base qw( Rose::DB );
+ database => 'advent_example.db',
+ driver => 'sqlite'
+Now we need a script to create the Catalyst application. The first
+thing we'll do is create a simple database schema using MyDB. Then,
+we'll bootstrap a Catalyst application called MyApp. And finally,
+fill out MyApp with full-featured CRUD functionality.
+ use MyDB;
+ use Rose::DBx::Garden::Catalyst;
+ my $db = MyDB->new();
+ $db->dbh->do("CREATE TABLE foo (
+ id integer primary key,
+ name varchar(128)
+ system("catalyst.pl MyApp") and die $!;
+ my $garden = Rose::DBx::Garden::Catalyst->new(
+ db => $db,
+ catalyst_prefix => 'MyApp',
+ find_schemas => 0,
+Now start up your app and point your browser at L<http://localhost:3000/rdgc/>.
+B<NOTE:> In order for your app to find MyDB.pm you need to make sure it is in
+@INC, so start up your app from the current dir like:
+ perl MyApp/script/myapp_server.pl
+or explicitly include the current dir like:
+ cd MyApp && perl -I.. script/myapp_server.pl
+In a real-world application you might instead modify @INC with a C<use lib> in
+=head2 CRUD? Again?!?
+I know. CRUD is so, like, 1995.
+CRUD (Create, Read, Update, Delete) web applications are just
+about the oldest, most ubiquitous type of web app around. That makes them boring,
+right? Or at the very least, a wheel that has been invented so many
+times that it isn't worth your time. And yet, so many projects involve
+at least some level of CRUD functionality. We're not rid of CRUD yet, even
+if the glamour is long faded.
+At least, that's what I thought recently when I set about building a CRUD app
+for what seemed like the 1000th time. This time, I thought, is the last time
+I write all that foundational code by hand. If building CRUD apps is like
+shoveling snow, I wanted to buy a snowblower.
+I was charged with designing both the database schema and the web application
+that would front it. I knew several things:
+My preferred ORM and form-manager packages
+were Rose::DB::Object and Rose::HTML::Objects.
+The database schema was going to require several iterations
+of "write, get customer feedback, re-write."
+Trying to keep all the Perl (not to mention XHTML
+especially in the early days while the schema was still in flux. And yet I
+have found that the most effective way to get customer feedback to a web
+application is to give them a web application to look at.
+Any serious web app is always going to have project-specific
+data validation requirements ("business logic"), so any kind of abstraction
+layer I tried to write for "generic CRUD" was going to have to be easy to
+extend and customize later.
+I wanted to bootstrap a web application that
+allowed me to do basic CRUD on the dummy data with which I was developing
+the schema, but that would form the legitimate basis of a real application
+later. This wasn't a "quick disposable prototype" (though those have
+their purpose). This was a "how much code can I generate automatically
+without it being either (a) too project-specific or (b) too simple
+to use later."
+After all, this wasn't going to be the last CRUD app I ever wrote, so
+I wanted to build something that I could use again for the next one. And
+the next, and ... well, you get the picture.
+=head2 Planting a Garden
+The result is L<Rose::DBx::Garden::Catalyst>. RDGC is a code
+and template generator similar in spirit to
+L<Catalyst::Example::InstantCRUD>, but it uses the Rose packages instead
+of DBIC and HTML::Widget. And it incorporates the sexy AJAXy goodness
+of the YUI toolkit.
+=head2 Best Practices
+RDGC tries to follow best practices for the Rose packages and for Catalyst.
+The basic philosophy is a single base class from
+which each part of the application
+(RDBO, RHTMLO, Controller, Model) could inherit,
+and a single base template for each
+view. RDGC also sticks all its code in its own namespace, so you can
+use it to generate CRUD code for your already-existing Catalyst apps.
+Most importantly, RDGC lays out its files in a structure that makes it
+straightforward to extend the basic CRUD features and
+add project-specific logic later. For more on the file/class structure
+RDGC uses, see the L<CataystX::CRUD::Tutorial>.
+The L<CatalystX::CRUD> project's ambition is to implement a single, simple API
+for a variety of ORM and form packages. The idea is that it ought to be
+possible to exchange RDBO for DBIC, or RHTMLO for L<HTML::FormFu> or
+L<Form::Processor>, and make minimal changes to your Catalyst code. The
+RDBO Model and RHTMLO Controller are the most mature parts of CatalystX::CRUD
+project, since they were first incarnated as Catalyst::Model::RDBO
+and Catalyst::Controller::Rose and went through real-world production
+testing before morphing into CatalystX::CRUD. But there's a DBIC Model
+currently in testing and plans for other form manager implementations.
+=head2 CRUD is Dead. Long Live CRUD!
+It's important to emphasize that RDGC is not intended to produce
+a final product. It can certainly be used as a rapid prototyping tool.
+But hopefully it also lays out a structure that encourages
+Catalyst and Rose best practices and makes it easier to extend
+and customize your application.
+Point RDGC at an existing database and try it out. If nothing else,
+the YUI data table feature is a handy way to quickly search, browse
+and page through your existing data.
+=head1 SEE ALSO
+Peter Karman E<lt>karman at cpan dot orgE<gt>