]> git.decadent.org.uk Git - maypole.git/blob - lib/Maypole/Manual/Model.pod
fixed typo in factory/edit template
[maypole.git] / lib / Maypole / Manual / Model.pod
1 =head1 NAME
2
3 Maypole::Manual::Model - Maypole Model Classes
4
5 =head1 DESCRIPTION
6
7 Maypole's model classes provide an interface to your data store.
8 In principle Maypole can connect to pretty much any data source,
9 but the default model is based on the popular L<Class::DBI> object
10 interface that uses the near-universal L<DBI> Perl interface to databases.
11
12 =head2 Maypole::Model::CDBI
13
14 Maypole model classes are pretty evil. The very first thing a Maypole
15 model class will do in a Maypole application is to cause a load of
16 table-based classes to come into being, and then assimilate them.
17
18 What I mean by this is that when you set up a Maypole application, in
19 your driver class, you'll say something like this:
20
21     BeerDB->setup("dbi:mysql:beerdb");
22
23 C<setup> is a Maypole method, and it hands its parameter to the model
24 class. In our case, the argument is a DBI connect string, because
25 that's what C<Maypole::Model::CDBI>, the C<Class::DBI>-based model
26 expects. C<Maypole::Model::CDBI> has a method called C<setup_database>
27 that creates all the C<Class::DBI> table classes after connecting to the
28 database with that connect string. It does this by using
29 C<Class::DBI::Loader>, a utility module which asks a database
30 about its schema and sets up classes such as C<BeerDB::Beer> to inherit
31 from C<Class::DBI>.
32
33 Now it gets interesting. The names of these classes are stashed away in
34 the application's configuration, and then Maypole forcibly has these
35 classes inherit from the model class. Our C<BeerDB::Beer> now inherits
36 both from C<Class::DBI> and C<Maypole::Model::CDBI>.
37
38 This is useful for two reasons. The first reason is that
39 C<Maypole::Model::CDBI> is stuffed full of C<Class::DBI> goodies that
40 make writing Maypole applications a lot easier:
41
42     package Maypole::Model::CDBI;
43     use base qw(Maypole::Model::Base Class::DBI);
44     use Maypole::Model::CDBI::AsForm;
45     use Class::DBI::FromCGI;  # probabyly broken . 
46     use Class::DBI::Loader;
47     use Class::DBI::AbstractSearch;
48     use Class::DBI::Plugin::RetrieveAll;
49     use Class::DBI::Pager;
50
51 We'll meet most of these goodies in the
52 L<Standard Templates and Actions|Maypole::Manual::StandardTemplates>
53 chapter, where we explain how C<Maypole::Model::CDBI> works.
54
55 The second reason why we want our table classes to inherit from
56 C<Maypole::Model::CDBI> is because it provides a useful set of 
57 default actions. So what's an action, and why are they useful?
58
59
60 =head2 Maypole::Model::CDBI::Plain
61
62 The 'Plain' maypole Model : C<Maypole::Model::CDBI> allows you
63
64     package Foo;
65     use 'Maypole::Application';
66
67     Foo->config->model("Maypole::Model::CDBI::Plain");
68     Foo->setup([qw/ Foo::SomeTable Foo::Other::Table /]);
69
70     # untaint columns and provide custom actions for each class
71
72     Foo::SomeTable->untaint_columns(email => ['email'], printable => [qw/name description/]);
73
74     Foo::Other::Table->untaint_columns ( ... );
75
76     sub Foo::SomeTable::SomeAction : Exported {
77
78         . . .
79
80     }
81
82 =head2 Extending a model class with actions
83
84 Maypole operates primarily by turning URLs into method calls on a model
85 class. All that the model stage of Maypole's operation does, when it
86 comes down to it, is maintain a mapping of tables to classes, and
87 despatch a HTTP request to a method call on the relevant table class. This
88 means that if you request a URL such as
89
90     http://localhost/beerdb/brewery/delete/20
91
92 Maypole's first stage of operation is to turn that into
93 C<BeerDB::Brewery-E<gt>delete(20)>. Now, it's slightly more complex than
94 that. Firstly because it doesn't actually pass the parameter C<20>, but
95 it passes an object representing row 20 in the database, but we can
96 gloss over that for the second. No, the real issue is that Maypole does
97 not allow you to call just any method in the table class; that would be
98 somewhat insecure. 
99
100 Instead, Maypole makes a distinction between the kind of methods that
101 only the class itself and other Perl code can call, and the kind of
102 methods that anyone can call from a URL. This latter set of methods are
103 called B<exported> methods, and exporting is done by means of Perl
104 attributes. You define a method to be exported like so:
105
106     sub drink :Exported {
107
108 This will allow the user to access C</beerdb/beer/drink> over the web.
109 An exported method accompanied with a template to render its output is
110 sometimes called an B<action>. 
111
112 Maypole model classes like C<Maypole::Model::CDBI> come with a
113 relatively handy set of actions which are all you need to set up a CRUD
114 (Create, Read, Update, Delete)
115 database front-end: viewing a row in a database, editing it, adding a
116 new one, deleting, and so on. The most important thing about Maypole,
117 though, is that it doesn't stop there. You can add your own.
118
119 For instance, in our beer database application, we could create a
120 C<BeerDB::Beer> package, and put some additional actions in there.
121
122     package BeerDB::Beer;
123     sub top_five :Exported {
124         my ($class, $r) = @_;
125         $r->objects([ ($r->retrieve_all_sorted_by("score"))[-5..-1] ]);
126     }
127
128 Our action is called as a class method with the Maypole request object.
129 It uses the C<Class::DBI::Plugin::RetrieveAll> module's
130 C<retrieve_all_sorted_by> mixin to get the top five scoring beers, and
131 puts these in the C<objects> slot of the request of object. Next, the
132 view class will come along and process the C<top_five> template with
133 these five beers.
134
135 We'll look more at how to put together actions in the
136 L<Standard Templates and Actions|Maypole::Manual::StandardTemplates>
137 chapter and our case studies.
138
139 =head2 Links
140
141 L<Contents|Maypole::Manual>,
142 Next L<Maypole View Classes|Maypole::Manual::View>,
143 Previous L<Introduction to Maypole|Maypole::Manual::About>
144
145 =cut