X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=lib%2FMaypole%2FManual%2FModel.pod;h=98f54cd093c495b800a66459a5d676c139d21b5c;hb=e8ebb9e2413d25fe7accc675387dfad270d7367e;hp=bc54ffdb8105ef81a9e57e260c820816fbb445f1;hpb=616082000cbe7305fbfc84d33bb2f9d53cc86f3c;p=maypole.git diff --git a/lib/Maypole/Manual/Model.pod b/lib/Maypole/Manual/Model.pod index bc54ffd..98f54cd 100644 --- a/lib/Maypole/Manual/Model.pod +++ b/lib/Maypole/Manual/Model.pod @@ -1,6 +1,13 @@ -=head1 Maypole Model Classes +=head1 NAME -=head2 Class::DBI +Maypole::Manual::Model - Maypole Model Classes + +=head1 DESCRIPTION + +Maypole's model classes provide an interface to your data store. +In principle Maypole can connect to pretty much any data source, +but the default model is based on the popular L object +interface that uses the near-universal L Perl interface to databases. =head2 Maypole::Model::CDBI @@ -14,15 +21,14 @@ your driver class, you'll say something like this: BeerDB->setup("dbi:mysql:beerdb"); C is a Maypole method, and it hands its parameter to the model -class. In our case, the model class is a DBI connect string, because +class. In our case, the argument is a DBI connect string, because that's what C, the C-based model expects. C has a method called C that creates all the C table classes after connecting to the database with that connect string. It does this by using C, a utility module which asks a database about its schema and sets up classes such as C to inherit -from C. This is just doing automatically what we did -manually in our examples above. +from C. Now it gets interesting. The names of these classes are stashed away in the application's configuration, and then Maypole forcibly has these @@ -35,20 +41,44 @@ make writing Maypole applications a lot easier: package Maypole::Model::CDBI; use base qw(Maypole::Model::Base Class::DBI); - use Class::DBI::AsForm; - use Class::DBI::FromCGI; + use Maypole::Model::CDBI::AsForm; + use Class::DBI::FromCGI; # probabyly broken . use Class::DBI::Loader; use Class::DBI::AbstractSearch; use Class::DBI::Plugin::RetrieveAll; use Class::DBI::Pager; -We'll meet most of these goodies in L, where we -explain how C works. +We'll meet most of these goodies in the +L +chapter, where we explain how C works. The second reason why we want our table classes to inherit from -C is because C provides a useful set of +C is because it provides a useful set of default actions. So what's an action, and why are they useful? + +=head2 Maypole::Model::CDBI::Plain + +The 'Plain' maypole Model : C allows you + + package Foo; + use 'Maypole::Application'; + + Foo->config->model("Maypole::Model::CDBI::Plain"); + Foo->setup([qw/ Foo::SomeTable Foo::Other::Table /]); + + # untaint columns and provide custom actions for each class + + Foo::SomeTable->untaint_columns(email => ['email'], printable => [qw/name description/]); + + Foo::Other::Table->untaint_columns ( ... ); + + sub Foo::SomeTable::SomeAction : Exported { + + . . . + + } + =head2 Extending a model class with actions Maypole operates primarily by turning URLs into method calls on a model @@ -64,13 +94,13 @@ Cdelete(20)>. Now, it's slightly more complex than that. Firstly because it doesn't actually pass the parameter C<20>, but it passes an object representing row 20 in the database, but we can gloss over that for the second. No, the real issue is that Maypole does -not allow you to call any method in the table class; that would be +not allow you to call just any method in the table class; that would be somewhat insecure. Instead, Maypole makes a distinction between the kind of methods that only the class itself and other Perl code can call, and the kind of methods that anyone can call from a URL. This latter set of methods are -called B methods, and exporting is done with by means of Perl +called B methods, and exporting is done by means of Perl attributes. You define a method to be exported like so: sub drink :Exported { @@ -81,6 +111,7 @@ sometimes called an B. Maypole model classes like C come with a relatively handy set of actions which are all you need to set up a CRUD +(Create, Read, Update, Delete) database front-end: viewing a row in a database, editing it, adding a new one, deleting, and so on. The most important thing about Maypole, though, is that it doesn't stop there. You can add your own. @@ -91,7 +122,7 @@ C package, and put some additional actions in there. package BeerDB::Beer; sub top_five :Exported { my ($class, $r) = @_; - $r->{objects} = [ ($r->retrieve_all_sorted_by("score"))[-5..-1] ]; + $r->objects([ ($r->retrieve_all_sorted_by("score"))[-5..-1] ]); } Our action is called as a class method with the Maypole request object. @@ -102,8 +133,13 @@ view class will come along and process the C template with these five beers. We'll look more at how to put together actions in the -L chapter and our case studies. +L +chapter and our case studies. + +=head2 Links -=head2 What Maypole wants from a model +L, +Next L, +Previous L -=head2 Building your own model class +=cut