File Coverage

blib/lib/Model/Envoy/Set.pm
Criterion Covered Total %
statement 28 28 100.0
branch 5 6 83.3
condition n/a
subroutine 10 10 100.0
pod 6 6 100.0
total 49 50 98.0


line stmt bran cond sub pod time code
1             package Model::Envoy::Set;
2              
3 5     5   5672 use MooseX::Role::Parameterized;
  5         363881  
  5         33  
4 5     5   164890 use Module::Runtime 'use_module';
  5         14  
  5         53  
5 5     5   312 use Moose::Util::TypeConstraints;
  5         13  
  5         48  
6              
7             our $VERSION = '0.3.0';
8              
9             =head1 Model::Envoy::Set
10              
11             A role for creating, finding and listing Model::Envoy based objects. Similar in
12             philosophy to DBIx::Class::ResultSets.
13              
14             =head2 Synopsis
15              
16             package My::Models;
17              
18             use Moose;
19             with 'Model::Envoy::Set' => { namespace => 'My::Envoy' };
20              
21              
22             ....then later...
23              
24             my $widget = My::Models->m('Widget')->fetch( id => 2 );
25              
26             $widget->name('renamed');
27             $widget->save;
28              
29              
30             =head2 Configuration
31              
32             When incorporating this role into your class, you will need to specify the perl namespace where
33             your model classes reside per the synopsis above.
34              
35             =head2 Methods
36              
37             =head3 m($type)
38              
39             Returns an Envoy::Set of the specified $type. So for a class My::Model::Foo
40              
41             my $set = My::Models->m('Foo');
42              
43             =head3 build(\%params)
44              
45             Create a new instance of the Model::Envoy based class referenced by the set:
46              
47             my $instance = $set->build({
48             attribute => $value,
49             ...
50             });
51              
52             =head3 fetch(%params)
53              
54             Retrieve an object from storage
55              
56             my $model = $set->fetch( id => 1 );
57              
58             =head3 list(%params)
59              
60             Query storage and return a list of objects that matched the query
61              
62             my $models = $set->list(
63             color => 'green',
64             size => 'small',
65             ...
66             );
67              
68             =head3 get_storage($storage_package)
69              
70             Passes back the storage plugin specified by C<$storage_package> being used by the set's model type.
71             Follows the same namespace resolution process as the C<Model::Envoy> method of the same name.
72              
73             =head3 load_types(@names)
74              
75             For now Model::Envoy does not slurp all the classes in a certain namespace
76             for use with $set->m(). Call load_types() at the start of your program instead:
77              
78             My::Models->load_types( qw( Foo Bar Baz ) );
79              
80             =cut
81              
82              
83             parameter namespace => (
84             isa => 'Str',
85             required => 1,
86             );
87              
88             role {
89              
90             my $namespace = shift->namespace;
91              
92             method '_namespace' => sub {
93 18     18   51 $namespace;
94             };
95             };
96              
97             has model_class => (
98             is => 'rw',
99             isa => 'Str',
100             required => 1,
101             );
102              
103             sub m {
104 4     4 1 589635 my ( $class, $name ) = @_;
105              
106 4         23 my $namespace = $class->_namespace;
107              
108 4         88 $name =~ s/^$namespace\:://;
109              
110 4         60 return $class->new( model_class => "$namespace\::$name" );
111             }
112              
113             sub build {
114 3     3 1 1118 my( $self, $params, $no_rel ) = @_;
115              
116 3         135 return $self->model_class->build($params,$no_rel);
117             }
118             sub fetch {
119 13     13 1 48675 my $self = shift;
120              
121 13 100       42 return undef unless @_;
122 12         456 return $self->model_class->_dispatch('fetch', @_ );
123             }
124              
125             sub list {
126 7     7 1 24320 my $self = shift;
127              
128 7         274 return $self->model_class->_dispatch('list', @_ );
129              
130             }
131              
132             sub get_storage {
133 2     2 1 687 my $self = shift;
134              
135 2         65 $self->model_class->get_storage(@_);
136             }
137              
138             sub load_types {
139 14     14 1 1654791 my ( $self, @types ) = @_;
140              
141 14         47 my $namespace = $self->_namespace;
142              
143 14         35 foreach my $type ( @types ) {
144              
145 18 100       27224 die "invalid type name '$type'" unless $type =~ /^[a-z]+$/i;
146              
147 13 50       71 use_module("$namespace\::$type")
148             or die "Could not load model type '$type'";
149             }
150             }
151              
152             1;