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