File Coverage

blib/lib/Catalyst/Model/Curio.pm
Criterion Covered Total %
statement 47 47 100.0
branch 5 6 83.3
condition 3 3 100.0
subroutine 12 12 100.0
pod n/a
total 67 68 98.5


line stmt bran cond sub pod time code
1             package Catalyst::Model::Curio;
2             our $VERSION = '0.03';
3              
4             =encoding utf8
5              
6             =head1 NAME
7              
8             Catalyst::Model::Curio - Curio Model for Catalyst.
9              
10             =head1 SYNOPSIS
11              
12             Create your model class:
13              
14             package MyApp::Model::Cache;
15            
16             use Moo;
17             use strictures 2;
18             use namespace::clean;
19            
20             extends 'Catalyst::Model::Curio';
21            
22             __PACKAGE__->config(
23             class => 'MyApp::Service::Cache',
24             );
25            
26             1;
27              
28             Then use it in your controllers:
29              
30             my $chi = $c->model('Cache::geo_ip');
31              
32             =head1 DESCRIPTION
33              
34             This module glues L<Curio> classes into Catalyst's model system.
35              
36             This distribution also comes with L<Catalyst::Helper::Model::Curio>
37             which makes it somewhat simpler to create your Catalyst model class.
38              
39             You may want to check out L<Curio/Use Curio Directly> for an
40             alternative viewpoint on using Catalyst models when you are
41             already using Curio.
42              
43             =cut
44              
45 1     1   2388719 use Curio qw();
  1         172942  
  1         32  
46 1     1   10 use Module::Runtime qw( require_module );
  1         2  
  1         5  
47 1     1   56 use Types::Common::String qw( NonEmptySimpleStr );
  1         4  
  1         11  
48 1     1   598 use Types::Standard qw( Bool );
  1         2  
  1         7  
49              
50 1     1   678 use Moo;
  1         3  
  1         7  
51 1     1   2532 use strictures 2;
  1         6  
  1         37  
52 1     1   168 use namespace::clean;
  1         2  
  1         4  
53              
54             extends 'Catalyst::Model';
55              
56             our $_KEY;
57              
58             my %installed_key_model_classes;
59              
60             sub BUILD {
61 3     3   94678 my ($self) = @_;
62              
63             # Get the Curio class loaded early.
64 3         29 require_module( $self->class() );
65              
66 3         29509 $self->_install_key_models();
67              
68 3         27 return;
69             }
70              
71             sub ACCEPT_CONTEXT {
72 9     9   168528 my ($self) = @_;
73              
74 9         53 my $method = $self->method();
75              
76 9   100     105 my $key = $self->key() || $_KEY;
77              
78 9 100       125 return $self->class->$method(
79             $key ? $key : (),
80             );
81             }
82              
83             sub _install_key_models {
84 3     3   8 my ($self) = @_;
85              
86 3 100       17 return if $self->key();
87              
88 2         19 my $model_class = ref( $self );
89 2 50       10 return if $installed_key_model_classes{ $model_class };
90              
91 2         4 my $model_name = $model_class;
92 2         18 $model_name =~ s{^.*::(?:Model|M)::}{};
93              
94 2         4 foreach my $key (@{ $self->class->declared_keys() }) {
  2         7  
95 1     1   503 no strict 'refs';
  1         3  
  1         214  
96              
97 5         39 *{"$model_class\::$key\::ACCEPT_CONTEXT"} = sub{
98 3     3   63626 my ($self, $c) = @_;
99 3         11 local $_KEY = $key;
100 3         16 return $c->model( $model_name );
101 5         70 };
102             }
103              
104 2         7 $installed_key_model_classes{ $model_class } = 1;
105              
106 2         7 return;
107             }
108              
109             =head1 CONFIG ARGUMENTS
110              
111             =head2 class
112              
113             class => 'MyApp::Service::Cache',
114              
115             The Curio class that this model wraps around.
116              
117             This is required to be set, otherwise Catalyst will throw
118             and exception when trying to load your model.
119              
120             =cut
121              
122             has class => (
123             is => 'ro',
124             isa => NonEmptySimpleStr,
125             required => 1,
126             );
127              
128             =head2 key
129              
130             key => 'geo_ip',
131              
132             If your Curio class supports keys then, if set, this forces
133             your model to interact with one key only.
134              
135             =cut
136              
137             has key => (
138             is => 'ro',
139             isa => NonEmptySimpleStr,
140             );
141              
142             =head2 method
143              
144             method => 'connect',
145              
146             By default Catalyst's C<model()> will call the C<fetch()>
147             method on your L</class> which will return a Curio object.
148             If you'd like, you can change this to call a different
149             method, returning something else of your choice.
150              
151             You could, for example, have a method in your Curio class
152             which returns the the resource that your Curio object makes:
153              
154             sub connect {
155             my $class = shift;
156             return $class->fetch( @_ )->chi();
157             }
158              
159             Then set the C<method> to C<connect> causing C<model()> to
160             return the CHI object instead of the Curio object.
161              
162             =cut
163              
164             has method => (
165             is => 'ro',
166             isa => NonEmptySimpleStr,
167             default => 'fetch',
168             );
169              
170             1;
171             __END__
172              
173             =head1 HANDLING KEYS
174              
175             =head2 No Keys
176              
177             A Curio class which does not support keys just means you don't
178             set the L</key> config argument.
179              
180             =head2 Single Key
181              
182             If your Curio class does support keys you can choose to create a model
183             for each key you want exposed in catalyst by specifying the L</key>
184             config argument in each model for each key you want available in Catalyst.
185             Each model would have the same L</class>.
186              
187             =head2 Multiple Keys
188              
189             If your Curio class supports keys and you do not set the L</key>
190             config argument then the model will automatically create pseudo
191             models for each key.
192              
193             This is done by appending each declared key to your model name.
194             You can see this in the L</SYNOPSIS> where the model name is
195             C<Cache> but since L</key> is not set, and the Curio class does
196             have declared keys then the way you get the model is by appending
197             C<::geo_ip> to the model name, or whatever key you want to access.
198              
199             =head1 SUPPORT
200              
201             Please submit bugs and feature requests to the
202             Catalyst-Model-Curio GitHub issue tracker:
203              
204             L<https://github.com/bluefeet/Catalyst-Model-Curio/issues>
205              
206             =head1 ACKNOWLEDGEMENTS
207              
208             Thanks to L<ZipRecruiter|https://www.ziprecruiter.com/>
209             for encouraging their employees to contribute back to the open
210             source ecosystem. Without their dedication to quality software
211             development this distribution would not exist.
212              
213             =head1 AUTHORS
214              
215             Aran Clary Deltac <bluefeet@gmail.com>
216              
217             =head1 COPYRIGHT AND LICENSE
218              
219             Copyright (C) 2019 Aran Clary Deltac
220              
221             This program is free software: you can redistribute it and/or modify
222             it under the terms of the GNU General Public License as published by
223             the Free Software Foundation, either version 3 of the License, or
224             (at your option) any later version.
225              
226             This program is distributed in the hope that it will be useful,
227             but WITHOUT ANY WARRANTY; without even the implied warranty of
228             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
229             GNU General Public License for more details.
230              
231             You should have received a copy of the GNU General Public License
232             along with this program. If not, see L<http://www.gnu.org/licenses/>.
233              
234             =cut
235