\r
+\r
|\r
- +-- --+\r
- |\r
+ +- -+\r
|\r
+\r
\r
custom driver class (BeerDB.pm), a set of auto-generated model classes, and a \r
view class: \r
\r
- THE DRIVER\r
+\r
+ THE DRIVER\r
+------- init() is a factory method,\r
1 Maypole | it sets up the view\r
Maypole::Config <----- config(); | classes\r
model(); init(); *-------+ THE VIEW\r
- | view_object(); -------+ \r
+ | view_object(); -------+\r
| +--------------* setup(); | Maypole::View::Base\r
| | + | +\r
| | | | 1 |\r
- | | Apache::MVC *-----+ +-----> Maypole::View::TT\r
- | | + | (or another view class)\r
- | | | |\r
- | | PLUGINS |\r
- | | + |\r
- | | | +----- or CGI::Maypole\r
- | | BeerDB or MasonX:::Maypole\r
+ | | PLUGINS Apache::MVC *-----+ +-----> Maypole::View::TT\r
+ | | + + | (or another view class)\r
+ | | | | |\r
+ | | +-----+-----+ |\r
+ | | | |\r
+ | | BeerDB +----- or CGI::Maypole\r
+ | | or MasonX:::Maypole\r
| |\r
| setup() is a factory method,\r
| it sets up the model\r
| classes\r
|\r
- | THE MODEL\r
+ | THE MODEL\r
|\r
- | Maypole::Model::Base Class::DBI\r
- | + +\r
- | | | \r
- +-------> Maypole::Model::CDBI \r
- + \r
- | \r
+ | Maypole::Model::Base Class::DBI\r
+ | + + +\r
+ | | | |\r
+ +-------> Maypole::Model::CDBI Class::DBI::<db_driver>\r
+ + +\r
+ | |\r
+------------+--------+-------+---------+\r
| | | | |\r
BeerDB::Pub | BeerDB::Beer | BeerDB::Brewery\r
pub(); BeerDB::Style\r
beer(); beers();\r
\r
-\r
=head2 What about Maypole::Application - loading plugins\r
\r
-The main job of L<Maypole::Application> is to insert the plugins into the \r
-hierarchy. It ensures that L<BeerDB> inherits from the first plugin, which \r
-inherits from the next, etc., until the last plugin inherits from the frontend. \r
-\r
-It is also the responsibility of L<Maypole::Application> to decide which \r
-frontend to use. \r
+The main job of L<Maypole::Application> is to insert the plugins into the\r
+hierarchy. It is also the responsibility of L<Maypole::Application> to decide\r
+which frontend to use. It builds the list of plugins, then pushes them onto the\r
+driver's C<@ISA>, then pushes the frontend onto the end of the driver's C<@ISA>.\r
+So method lookup first searches all the plugins, before searching the frontend\r
+and finally L<Maypole> itself.\r
\r
From Maypole 2.11, L<Maypole::Application> makes no appearance in the\r
inheritance structure of a Maypole application. (In prior versions,\r
L<Maypole::Application> would make itself inherit the plugins, and then insert\r
itself in the hierarchy, but this was unnecessary).\r
\r
-The order of inheritance is the same as the order in which plugins are supplied \r
-in the C<use Maypole::Application> statement. \r
-\r
=head2 Who builds the model?\r
\r
First, remember we are talking about the standard, unmodified Maypole here. \r
\r
The standard model is built in 3 stages. \r
\r
-First, C<Maypole::setup> calls C<setup_database> on the Maypole model class, in\r
-this case L<Maypole::Model::CDBI>. C<setup_database> then uses\r
+First, C<Maypole::setup_model> calls C<setup_database> on the Maypole model\r
+class, in this case L<Maypole::Model::CDBI>. C<setup_database> then uses\r
L<Class::DBI::Loader> to autogenerate individual L<Class::DBI> classes for each\r
of the tables in the database (C<BeerDB::Beer>, C<BeerDB::Pub> etc).\r
+L<Class::DBI::Loader> identifies the appropriate L<Class::DBI> subclass and\r
+inserts it into each of these table classes' C<@ISA> ( C<<\r
+Class::DBI::<db_driver> >> in the diagrams)..\r
\r
Next, C<Maypole::setup> B<unshifts> L<Maypole::Model::CDBI> onto the C<@ISA> \r
array of each of these classes. \r
use base 'OfflineBeer::Beer';\r
1;\r
\r
-This package will be loaded automatically during C<setup()>, and\r
-C<BeerDB2::Maypole::Model> is B<unshifted> onto it's C<@ISA>. \r
+From Maypole 2.11, this package will be loaded automatically during C<setup()>,\r
+and C<BeerDB2::Maypole::Model> is B<unshifted> onto it's C<@ISA>.\r
\r
Configure relationships either in the individual C<OfflineBeer::*> classes, or\r
else all together in C<OfflineBeer> itself i.e. not in the Maypole model. This \r
|\r
Maypole::Model::Base |\r
+ |\r
- | +----------------------+-----------------+\r
- | | |\r
- | | |\r
- Maypole::Model::CDBI | OFFLINE\r
- + | MODEL\r
- | |\r
- BeerDB2::Maypole::Model OfflineBeer\r
- + +\r
- | |\r
+ | +-----------------+----+-----------------+\r
+ | | | |\r
+ | | | |\r
+ Maypole::Model::CDBI | | OFFLINE\r
+ + | | MODEL\r
+ | | |\r
+ BeerDB2::Maypole::Model Class::DBI::<db_driver> OfflineBeer\r
+ + + +\r
+ | | |\r
+ +-----------------------------+ |\r
| |\r
+--- BeerDB2::Pub --------+ OfflineBeer::Pub --------+\r
| beers(); |\r
\r
=head3 Features\r
\r
-Non-Maypole applications using the Offline model are completely isolated from\r
+1. Non-Maypole applications using the Offline model are completely isolated from\r
the Maypole application, and need not know it exists at all.\r
\r
-Methods defined in the Maypole table classes, override methods defined in the\r
+2. Methods defined in the Maypole table classes, override methods defined in the\r
Offline table classes, because C<BeerDB2::Maypole::Model> was unshifted onto the\r
beginning of each Maypole table class's C<@ISA>. Perl's depth first,\r
left-to-right method lookup from e.g. C<BeerDB2::Beer> starts in\r
C<BeerDB2::Maypole::Model> and C<OfflineBeer>. Note that C<OfflineBeer::CDBI>\r
does not itself need to inherit from L<Class::DBI>.\r
\r
-Methods defined in the Maypole model base class (C<BeerDB2::Maypole::Model>),\r
+3. Methods defined in the Maypole model base class (C<BeerDB2::Maypole::Model>),\r
override methods in the individual Offline table classes, and in the Offline\r
model base class (C<Offline>). \r
\r
-Relationships defined in the Offline classes are inherited by the Maypole model.\r
+4. Relationships defined in the Offline classes are inherited by the Maypole\r
+model.\r
\r
-The Maypole model has full access to the underlying Offline model. \r
+5. The Maypole model has full access to the underlying Offline model. \r
\r
=head3 Theory \r
\r