The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Mojo::TypeModel - A very simple model system using Mojo::Base

DESCRIPTION

A model system using Mojo::Base and primarily for Mojolicious applications. The models can call other models and can pass data to them (like db connections).

Additionally, Mojolicious::Plugin::TypeModel is included to build helpers for models.

EXAMPLE

This is a (reduced) model from the CarPark application.

The base model is simply:

  package CarPark::Model;

  use Mojo::Base 'Mojo::TypeModel';

  use CarPark::Model::Door;
  use CarPark::Model::GPIO;
  use CarPark::Model::User;

  has config => sub { Carp::croak 'config is required' };
  has db => sub { Carp::croak 'db is required' };

  sub copies { state $copies = [qw/config db/] }

  sub types {
    state $types = {
      door => 'CarPark::Model::Door',
      gpio => 'CarPark::Model::GPIO',
      user => 'CarPark::Model::User',
    };
  }

Then a model class inherits from it

  package CarPark::Model::User;

  use Mojo::Base 'CarPark::Model';

  sub exists {
    my $self = shift;
    my $db = $self->db;
    # use db to check
  }

A model instance's "model" method is used to construct other models.

  package CarPark::Model::Door;

  use Mojo::Base 'CarPark::Model';

  sub is_open {
    my $self = shift;
    return !!$self->model('gpio')->pin_state(16);
  }

Helper methods may be installed via the plugin.

 package MyApp;

 use Mojo::Base 'Mojolicious';

 sub startup {
    my $app = shift;

    ...

    my $base = CarPark::Model->new(
      config => { ... },
      db => SomeDB->new(...),
    );

    $app->plugin(TypeModel => {base => $base});

    ...

    $app->routes->get('/door_state' => sub {
      my $c = shift;
      my $state = $c->model->door->is_open ? 'open' : 'closed';
      $c->render(text => "Door is $state");
    });
  }

The "copies" properties propagate when instantiated via another model instance's "model" method.

  my $exists = CarPark::Model->new(config => {...}, db => $db)->model('user')->exists;

... which with the plugin is the same as

  my $exists = $app->model->user->exists;

METHODS

copies

Returns an array reference of attributes that should be copied into child model instances. Meant to be overloaded by subclasses.

model

  my $user_model = $base->model(user => $overrides);

Takes a string type for the type to instantiate (see "types"). Optionally accepts a hash reference or list of key-value pairs of attribute overrides.

The type's class is instantiated. The "copies" attributes are copied from the invocant instance (the base) except where overrides were provided. The resulting instance is returned.

types

Returns a hash reference whose keys are types and the corresponding values are the classes that implement those types. Meant to be overloaded by subclasses.

SOURCE REPOSITORY

http://github.com/jberger/Mojo-TypeModel

AUTHOR

Joel Berger, <joel.a.berger@gmail.com>

CONTRIBUTORS

None yet.

COPYRIGHT AND LICENSE

Copyright (C) 2017 by "AUTHOR" and "CONTRIBUTORS". This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.