File Coverage

blib/lib/Mojo/TypeModel.pm
Criterion Covered Total %
statement 13 16 81.2
branch 2 4 50.0
condition n/a
subroutine 3 5 60.0
pod 3 3 100.0
total 21 28 75.0


line stmt bran cond sub pod time code
1             package Mojo::TypeModel;
2              
3 1     1   343155 use Mojo::Base -base;
  1         2  
  1         8  
4              
5             our $VERSION = '0.02';
6             $VERSION = eval $VERSION;
7              
8 1     1   175 use Carp ();
  1         2  
  1         194  
9              
10 0     0 1 0 sub copies { state $copies = [] }
11              
12             sub model {
13 5     5 1 8191 my ($self, $type, @args) = @_;
14             Carp::croak "type $type not understood"
15 5 50       20 unless my $class = $self->types->{$type};
16              
17 5 50       40 my %args = (@args == 1 ? %{$args[0]} : @args);
  0         0  
18 5         13 $args{$_} = $self->$_() for grep { !exists $args{$_} } @{ $self->copies };
  5         39  
  5         13  
19 5         43 return $class->new(%args);
20             }
21              
22 0     0 1   sub types { state $types = {} }
23              
24             1;
25              
26             =head1 NAME
27              
28             Mojo::TypeModel - A very simple model system using Mojo::Base
29              
30             =head1 DESCRIPTION
31              
32             A model system using L and primarily for L applications.
33             The models can call other models and can pass data to them (like db connections).
34              
35             Additionally, L is included to build helpers for models.
36              
37             =head1 EXAMPLE
38              
39             This is a (reduced) model from the L application.
40              
41             The base model is simply:
42              
43             package CarPark::Model;
44              
45             use Mojo::Base 'Mojo::TypeModel';
46              
47             use CarPark::Model::Door;
48             use CarPark::Model::GPIO;
49             use CarPark::Model::User;
50              
51             has config => sub { Carp::croak 'config is required' };
52             has db => sub { Carp::croak 'db is required' };
53              
54             sub copies { state $copies = [qw/config db/] }
55              
56             sub types {
57             state $types = {
58             door => 'CarPark::Model::Door',
59             gpio => 'CarPark::Model::GPIO',
60             user => 'CarPark::Model::User',
61             };
62             }
63              
64             Then a model class inherits from it
65              
66             package CarPark::Model::User;
67              
68             use Mojo::Base 'CarPark::Model';
69              
70             sub exists {
71             my $self = shift;
72             my $db = $self->db;
73             # use db to check
74             }
75              
76             A model instance's L method is used to construct other models.
77              
78             package CarPark::Model::Door;
79              
80             use Mojo::Base 'CarPark::Model';
81              
82             sub is_open {
83             my $self = shift;
84             return !!$self->model('gpio')->pin_state(16);
85             }
86              
87             Helper methods may be installed via the plugin.
88              
89             package MyApp;
90              
91             use Mojo::Base 'Mojolicious';
92              
93             sub startup {
94             my $app = shift;
95              
96             ...
97              
98             my $base = CarPark::Model->new(
99             config => { ... },
100             db => SomeDB->new(...),
101             );
102              
103             $app->plugin(TypeModel => {base => $base});
104              
105             ...
106              
107             $app->routes->get('/door_state' => sub {
108             my $c = shift;
109             my $state = $c->model->door->is_open ? 'open' : 'closed';
110             $c->render(text => "Door is $state");
111             });
112             }
113              
114             The L properties propagate when instantiated via another model instance's L method.
115              
116             my $exists = CarPark::Model->new(config => {...}, db => $db)->model('user')->exists;
117              
118             ... which with the plugin is the same as
119              
120             my $exists = $app->model->user->exists;
121              
122             =head1 METHODS
123              
124             =head2 copies
125              
126             Returns an array reference of attributes that should be copied into child model instances.
127             Meant to be overloaded by subclasses.
128              
129             =head2 model
130              
131             my $user_model = $base->model(user => $overrides);
132              
133             Takes a string type for the type to instantiate (see L).
134             Optionally accepts a hash reference or list of key-value pairs of attribute overrides.
135              
136             The type's class is instantiated.
137             The L attributes are copied from the invocant instance (the base) except where overrides were provided.
138             The resulting instance is returned.
139              
140             =head2 types
141              
142             Returns a hash reference whose keys are types and the corresponding values are the classes that implement those types.
143             Meant to be overloaded by subclasses.
144              
145             =head1 SOURCE REPOSITORY
146              
147             L
148              
149             =head1 AUTHOR
150              
151             Joel Berger, Ejoel.a.berger@gmail.comE
152              
153             =head1 CONTRIBUTORS
154              
155             =over
156              
157             =item None yet.
158              
159             =back
160              
161             =head1 COPYRIGHT AND LICENSE
162              
163             Copyright (C) 2017 by L and L.
164             This library is free software; you can redistribute it and/or modify
165             it under the same terms as Perl itself.
166