[Catalyst-commits] r7229 - trunk/examples/CatalystAdvent/root/2007/pen

karpet at dev.catalyst.perl.org karpet at dev.catalyst.perl.org
Wed Dec 5 02:10:57 GMT 2007

Author: karpet
Date: 2007-12-05 02:10:56 +0000 (Wed, 05 Dec 2007)
New Revision: 7229

day 10 ready

Modified: trunk/examples/CatalystAdvent/root/2007/pen/10.pod
--- 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>, 
+L<Rose::DB::Object>, L<Template::Toolkit>
+and the YUI CSS/Javascript library (L<http://developer.yahoo.com/yui/>).
+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 );
+ MyDB->register_db(
+    database    => 'advent_example.db',
+    driver      => 'sqlite'
+ );
+ 1;
+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.
+ #!/usr/bin/perl
+ 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,
+ );
+ $garden->plant('MyApp/lib');
+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
+ at 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:
+=item *
+My preferred ORM and form-manager packages
+were Rose::DB::Object and Rose::HTML::Objects. 
+=item *
+The database schema was going to require several iterations 
+of "write, get customer feedback, re-write."
+=item *
+Trying to keep all the Perl (not to mention XHTML
+and Javascript) in sync with the SQL was going to be a tedious process,
+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.
+=item *
+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. 
+=item *
+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>.
+=head2 CatalystX::CRUD
+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
 =head1 AUTHOR
-Peter Karman
+Peter Karman E<lt>karman at cpan dot orgE<gt>

More information about the Catalyst-commits mailing list