File Coverage

blib/lib/Catalyst/Model/DBIC/Schema/PerRequest.pm
Criterion Covered Total %
statement 34 36 94.4
branch 3 4 75.0
condition n/a
subroutine 10 11 90.9
pod 2 5 40.0
total 49 56 87.5


line stmt bran cond sub pod time code
1             package Catalyst::Model::DBIC::Schema::PerRequest;
2              
3             # ABSTRACT: Per request clone of a DBIC model with additional parameters
4              
5 1     1   2012233 use Moose;
  1         3  
  1         6  
6             extends 'Catalyst::Model';
7             with 'Catalyst::Component::InstancePerContext';
8              
9 1     1   4826 use Carp qw(croak confess);
  1         2  
  1         64  
10 1     1   5 use Module::Runtime qw(use_module);
  1         2  
  1         7  
11              
12             our $VERSION = '0.002002';
13              
14              
15              
16             has target_model => (
17             is => 'ro',
18             isa => 'Str',
19             required => 1,
20             );
21              
22              
23             has schema_class => (
24             is => 'ro',
25             isa => 'Str',
26             required => 1,
27             );
28              
29             #--------------------------------------------------------------------------#
30             # model_name
31             #--------------------------------------------------------------------------#
32              
33             has model_name => (
34             is => 'ro',
35             isa => 'Str',
36             lazy => 1,
37             builder => '_build_model_name',
38             );
39              
40             sub _build_model_name {
41 1     1   2 my $self = shift;
42              
43 1         3 my $class = ref($self);
44 1         7 (my $model_name = $class) =~ s/^[\w:]+::(?:Model|M):://;
45              
46 1         37 return $model_name;
47             }
48              
49              
50             #--------------------------------------------------------------------------#
51             # BUILD
52             #--------------------------------------------------------------------------#
53              
54             our %subnamespaces;
55             sub BUILD {
56 1     1 0 191940 my ($self) = @_;
57              
58 1 50       18 unless ($subnamespaces{ ref($self) }) {
59 1         9 $self->setup_subnamespaces;
60 1         4 $subnamespaces{ ref($self) } = 1;
61             }
62             }
63              
64             #--------------------------------------------------------------------------#
65             # setup_subnamespaces
66             #--------------------------------------------------------------------------#
67              
68             sub setup_subnamespaces {
69 1     1 0 2 my ($self) = @_;
70              
71 1         46 my $model_name = $self->model_name;
72 1         54 foreach my $source_name (use_module($self->schema_class)->sources) {
73 1     1   962 no strict 'refs';
  1         2  
  1         227  
74 1         11 *{ ref($self) . '::' . $source_name . '::ACCEPT_CONTEXT' } = sub {
75 1     1   17388 $_[1]->model($model_name)->schema->resultset($source_name);
76 1         72 };
77             }
78             }
79              
80             #--------------------------------------------------------------------------#
81             # build_per_context_instance
82             #--------------------------------------------------------------------------#
83              
84             sub build_per_context_instance {
85 3     3 0 27163 my ($self, $ctx) = @_;
86              
87 3 100       39 croak ref($self)
88             . ' is a per-request only model, calling it on the app makes no sense.'
89             unless blessed($ctx);
90              
91 2         82 my $target = $ctx->model($self->target_model);
92              
93 2         102 my $new = bless({%$target}, ref($target));
94              
95 2         33 $new->schema($self->per_request_schema($ctx, $new));
96              
97 2         1489 return $new;
98             }
99              
100              
101             # Thanks to Matt Trout (mst) for this idea
102             sub per_request_schema {
103 2     2 1 3 my ($self, $c, $original_model) = @_;
104              
105 2         65 return $original_model->schema->clone(
106             $self->per_request_schema_attributes($c, $original_model));
107             }
108              
109              
110             sub per_request_schema_attributes {
111 0     0 1   my ($self, $c, $original_model) = @_;
112              
113 0           confess
114             "Either per_request_schema_attributes needs to be created, or per_request_schema needs to be overridden!";
115             }
116              
117              
118             1; ## eof
119              
120             __END__
121              
122             =pod
123              
124             =encoding UTF-8
125              
126             =head1 NAME
127              
128             Catalyst::Model::DBIC::Schema::PerRequest - Per request clone of a DBIC model with additional parameters
129              
130             =head1 VERSION
131              
132             version 0.002002
133              
134             =head1 SYNOPSIS
135              
136             package MyApp::Model::RestrictedDB;
137              
138             use Moose;
139             extends 'Catalyst::Model::DBIC::Schema::PerRequest';
140              
141             __PACKAGE__->config(target_model => 'DB');
142              
143             sub per_request_schema_attributes {
144             my ($self, $c) = @_;
145             return (restricting_object => $c->user->obj);
146             }
147              
148             In your controller:
149              
150             $c->model('RestrictedDB')->resultset('...');
151              
152             =head1 DESCRIPTION
153              
154             Allows you to get a clone of an existing L<Catalyst::Model::DBIC::Schema>
155             model with additional parameters passed to the L<DBIx::Class::Schema> clone.
156              
157             =head1 ATTRIBUTES
158              
159             =head2 target_model
160              
161             The name of the original model class.
162              
163             or
164              
165             has '+target_model' => (
166             default => 'DB',
167             schema_class => 'MyApp::Schema',
168             );
169              
170             =head2 schema_class
171              
172             The name of your L<DBIx::Class> schema.
173              
174             =head1 METHODS
175              
176             =head2 per_request_schema($c, $original_model)
177              
178             This method is called automatically and will clone your schema with attributes
179             coming from L<per_request_schema_attributes>. You can override this method
180             directly to return a schema you want, but it's probably better to override
181             C<per_request_schema_attributes>.
182              
183             =head2 per_request_schema_attributes($c, $original_model)
184              
185             Override this method in your child class and return whatever parameters you
186             need for new schema instance.
187              
188             sub per_request_schema_attributes {
189             my ($self, $c, $original_model) = @_;
190             return (restricting_object => $c->user->obj);
191             }
192              
193             =head1 ACKNOWLEDGMENTS
194              
195             Thanks to mst (Matt S. Trout) for the idea and mentorship during the development.
196              
197             =head1 AUTHOR
198              
199             Roman F. <romanf@cpan.org>
200              
201             =head1 COPYRIGHT AND LICENSE
202              
203             This software is copyright (c) 2015 by Roman F..
204              
205             This is free software; you can redistribute it and/or modify it under
206             the same terms as the Perl 5 programming language system itself.
207              
208             =cut