+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+C<advent_example.db>.+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+@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+C<MyApp.pm>.+++=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:++=over++=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."++=back++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++L<CatalystX::CRUD::Tutorial>,+L<Rose::DB::Object::Tutorial>,+L<Rose::HTML::Form>,+L<http://developer.yahoo.com/yui/>+=head1 AUTHOR