[Catalyst-commits] r7327 - trunk/examples/CatalystAdvent/root/2007/pen

zamolxes at dev.catalyst.perl.org zamolxes at dev.catalyst.perl.org
Sun Dec 23 16:32:23 GMT 2007


Author: zamolxes
Date: 2007-12-23 16:32:23 +0000 (Sun, 23 Dec 2007)
New Revision: 7327

Added:
   trunk/examples/CatalystAdvent/root/2007/pen/adapter.pod
Log:
Catalyst::Model::Adaptor article


Added: trunk/examples/CatalystAdvent/root/2007/pen/adapter.pod
===================================================================
--- trunk/examples/CatalystAdvent/root/2007/pen/adapter.pod	                        (rev 0)
+++ trunk/examples/CatalystAdvent/root/2007/pen/adapter.pod	2007-12-23 16:32:23 UTC (rev 7327)
@@ -0,0 +1,127 @@
+=head1 Using plain classes as Catalyst models
+
+A common pitfall when designing models is the tendency to tie application
+logic to Catalyst. The problem with this approach is that model classes become
+difficult to reuse outside of Catalyst, which is a common requirement for most
+applications.
+A better design approach would be to write and test a plain class outside of
+your main web application, and then painlessly glue it to Catalyst with a
+couple lines of code.
+
+=head2 A review of Catalyst components
+
+=head3 The COMPONENT() method
+
+Catalyst gives you a chance to instantiate all your components (Models, Views
+and Controllers) during load time by calling the COMPONENT() method on each
+component class. This means you can implement it and return whatever you want
+from it. For models this boils down to:
+
+    package MyApp::Model::SomeClass;
+
+    use warnings;
+    use strict;
+    use base qw/Catalyst::Model/;
+
+    use SomeClass;
+
+    sub COMPONENT {
+        my($self, $c, @config) = @_;
+        return SomeClass->new(@config);
+    }
+
+    1;
+
+This particular implementation passes the configuration for this model to the
+external class on the call to new(). Of course, you could choose to instance
+the class any way you want to. Later on, C<$c-E<gt>model('SomeClass')> will get
+you the C<SomeClass> instance, B<not> C<MyApp::Model::SomeClass>. Notice that
+the returned object is the B<very same> instance that was created initially when
+your app was loaded.
+
+=head3 The ACCEPT_CONTEXT() method
+
+Every time C<$c-E<gt>model> is called, Catalyst gives you a chance to run custom
+logic by attempting to run ACCEPT_CONTEXT on the model, whatever is returned
+by this method is what C<$c-E<gt>model> returns as well. So, if you need a
+new instance on every call, your model becomes something like:
+
+    package MyApp::Model::SomeClass;
+
+    use warnings;
+    use strict;
+    use base qw/Catalyst::Model/;
+
+    use SomeClass;
+
+    sub ACCEPT_CONTEXT {
+        my($self, $c, @args) = @_;
+        return SomeClass->new(@args);
+    }
+
+    1;
+
+So when you call C<$c-E<gt>model('SomeClass')>, you'll get a fresh instance of
+C<SomeClass> B<not> C<MyApp::Model::SomeClass>.
+
+=head2 The C<Catalyst::Model::Adaptor> way
+
+Instead of implementing your own glue code, you can use the generic
+implementation provided by the C<Catalyst::Model::Adaptor> module, which
+provides several different ways of building your external class instances.
+
+If you need a single application-wide instance of your external class, you can
+inherit from C<Catalyst::Model::Adaptor>:
+
+    package MyApp::Model::Foo;
+
+    use warnings;
+    use strict;
+    use base qw/Catalyst::Model::Adaptor/;
+
+    __PACKAGE__->config(
+        class => 'SomeClass',
+        args  => {
+            foo => 'bar'
+        }
+    );
+
+    1;
+
+Of course, you can also configure your class via myapp.yaml
+
+    Model::Foo:
+        class: SomeClass
+        args:
+            foo: bar
+
+This gives you more flexibility when you decide to change your implementation,
+just replace C<SomeClass> with whatever class you wish to use, without even
+touching your code.
+
+=head3 Alternate object instancing approaches
+
+For instancing objects on every call to C<$c-E<gt>model>, just inherit from
+C<Catalyst::Model::Factory> instead. And for instancing objects on a
+per-request basis, inherit from C<Catalyst::Model::Factory::PerRequest>.
+The C<Catalyst::Model::Adaptor> documentation provides information on how to
+further customize your models to address your specific needs.
+
+=head3 For the incredibly lazy
+
+You can easily create glue models by using the helpers provided with
+C<Catalyst::Model::Adaptor>:
+
+    script/myapp_create.pl model SomeClass <type> MyApp::Model::SomeClass
+
+Where <type> can be C<Adaptor>, C<Factory> or C<Factory::PerRequest>.
+
+=head1 ACKNOWLEDGEMENTS
+
+Jonathan Rockway, for writing C<Catalyst::Model::Adaptor>.
+
+=head1 AUTHOR
+
+edenc - Eden Cardim - C<edencardim at gmail.com>
+
+=cut




More information about the Catalyst-commits mailing list