---
name: "Jifty::Manual::Models"
section: "3pm"
platform: "linux"
package: "libjifty-perl"
version: "1.10518+dfsg-2"
release: "Debian 7 (Wheezy)"
platforms: ["linux"]
url: "https://new.carta.tech/Jifty::Manual::Models"
---

# Jifty::Manual::Models(3pm)

Managing your datastore

## NAME

Jifty::Manual::Models - Managing your datastore

## DESCRIPTION

The idea behind a model is to give the user a database-independent way of defining how the data looks alike and how different parts of the data relate to each other. In database terms, you might think of a schema definition.

Besides the pure definition of a model, creation, updating and lookup of data are also possible in a comfortable way.

### Creating a model

Every model consists of two classes: *AppName*::Model::*ModelName* and *AppName*::Model::*ModelName*::Schema. Behind the scenes, a class named *AppName*::Model::*ModelName*Collection is created by Jifty::ClassLoader.

A simple model to store just one line of text might look like this:

```
    use strict;
    use warnings;
    package MyApp::Model::TextLine;
    use Jifty::DBI::Schema;
    use MyApp::Record schema {
        column 'textline';
    };
    # Your model-specific methods go here.
    1;
```

To create the database schema for a model inside an application you could simply run:

```
    jifty model --name TextLine
```

from inside your application's directory and Jifty will create exactly this class structure for you (minus the *column* line, to be precise).

*Schema definition language*

Creating a model has important side effects:

- •

  correctly type your data inside the data-store

- •

  let Jifty create (and update) your database schema for you

- •

  tell Jifty the behaviour in terms of form display

- •

  allow to work with multiple records (referred to as Collections) without effort

To get all these things done, Jifty allows one to describe the schema definition in a simply comprehensible but powerful syntax that looks more like written text than a programming language. The schema definition is made inside the `"MyApp::Model::XXX::Schema"` package and every single column to get created starts with the word `"column"` followed by the column's name.

A simple definition could look like this:

```
    column name =>
        type is 'text',
        label is 'Name',
        render as 'Text',
        since '0.0.1';
```

The following BNF shows the full syntax supported (omitting non-terminals that are self-explanatory to perl-developers):

```
    schema_definition ::= column_definition+
    column_definition ::= 'column' string_columnname '=>'
                          column_info [ ',' column_info ]+ ';'
    column_info ::= 'type' 'is' string
       | 'label' 'is' string
       | 'render_as' string
       | 'render' 'as' string
       | 'hints' 'is' string
       | 'refers_to' class_name 'by' string_columnname
       | 'default' 'is' string
       | 'literal' 'is' string
       | 'validator' 'is' subroutine_reference
       | 'immutable'
       | 'unreadable'
       | 'display_length' 'is' number
       | 'max_length' 'is' number
       | 'mandatory'
       | 'not_null'
       | 'distinct'
       | 'virtual'
       | 'computed'
       | 'sort_order' 'is' number
       | 'input_filters' 'are' string_classname
       | 'output_filters' 'are' string_classname
       | 'filters' 'are' string_classname
       | 'since' string_version_number
       | 'valid_values' 'are' array_of_valid_values
       | 'valid' 'are' array_of_valid_values
       | 'hints' 'are' string
    * 'is', 'by', 'on', 'as' and 'are' are fill-words that may get omitted.
```

For a full description of each parameter's meaning, look at Jifty::DBI::Schema.

*Versioning*

Every time you run the jifty utility with `"schema"` as an argument, Jifty will keep track on what it has done for you. To get that done, the version-number being stored in your application's config file `"etc/config.yml"` under the key named `"framework/Database/Verson"` is matched against your schema definition.

To force an update of your schema, simple create a new version number in your config file and modify your schema definition by using exactly this version number for every modified entry. After running

```
    jifty schema --setup
```

your database structure will be in sync to your schema definition. See Jifty::Manual::Upgrading for more information on model upgrading.

### Testing a model

After having created a schema, you might use the **ADMINISTRATION** Menu entry in Jifty's web view (i.e. the "pony") to browse through your models and add, edit or delete records in your database.

### The classes behind a model

- •

  MyApp::Model::Xxx

  This is the model-class you created to access individual records of your desired type. You will directly deal with objects of this class.

- •

  MyApp::Record

  All records of `"MyApp::Model::Xxx"` will have this class as their base class. Usually, this class will be automatically created by Jifty::ClassLoader for you. But, if you want to automatically enable all your records to do something, you will have a chance to do so by manually creating this class.

- •

  Jifty::Record

  This is the super-class of `"MyApp::Record"`. Inside this class, loading of records as well as the checking of user capabilities is done before going one level down to the database layer.

- •

  Jifty::DBI::Record

  This is the lowest-level class that the database stack provides. It directly deals with the underlying database.

- •

  App::Model::XxxCollection

  As the name applies, a collection is a set of typically more than one record. Every collection of this class consists of multiple `"App::Model::Xxx"` objects that can get retrieved from your data-store without explicit SQL statements, ordered by any criteria you give, paged in the fashion you like, and iterated sequentially or accessed at random order.

- •

  App::Collection

  Every collection of your schemata will have this class as its base. Usually this class is automatically created by Jifty::ClassLoader. If you intend to create new features for all of your collection this will be your chance to do.

- •

  Jifty::Collection

  This is the base class of an `"App::Collection"`, managing user capabilities on records it will keep track of.

- •

  Jifty::DBI::Collection

  This is the lowest-level base class that directly manages the access to the underlying database.

### Working with a single record

Working with a single record means working with objects of classes like `"MyApp::Model::Xxx"`. The typical creation and usage of a single record is:

```
    # create an object to allow data access
    my $object = new MyApp::Model::Xxx;
    # either create a representation in the DB
    $object->create(column => 'value', ...);
    # or load the data from DB somehow
    $object->load($id); # by a matching ID
    $object->load_by_cols(column => 'value', other_column => 'secondvalue');
    # try to load and if failed, create a record
    $object->load_or_create(column => 'value');
    # get the record's ID in the database
    # results in 'undef' if record is not valid (which usually means not found)
    my $id = $object->id;
    # delete the record from the database
    $object->delete;
```

To access data stored in different columns of a record you may use some of the automagically created methods on the object:

```
    # read some column named 'colname'
    my $value = $object->colname;
    # write some value to a column named 'colname'
    $object->set_colname($value);
    # get all columns in a single hash (not a reference!)
    my %record = $object->as_hash;
```

Especially, when writing to a record, you need not worry about how to write back the data to the database, the object will manage this step on its own.

### Working with multiple records

Working with more than one record of the same object-class brings collections into the game. Usually, a collection you deal with is of a type that conforms to your model name, `"MyApp::Model::XxxCollection"` and usually holds records of class `"MyApp::Model::Xxx"`. You typically use a collection like this:

```
    # create a collection object
    my $collection = new MyApp::Model::XxxCollection;
    # get all items of the model into the collection
    $collection->unlimit;
    # or restrict items to match some condition
    $collection->limit(column => 'colname', operator => '=', value => 42);
    # bring the items into some sorting order
    $collection->order_by(column => 'colname');
    # if neccesarry, directly jump to some record from the set
    $collection->goto_first_item;
    $collection->goto_item(42);
    # iterate through the result set
    while (my $record = $collection->next) {
          # do something with $record
    }
    # directly access the first or last item
    # be careful: this will set the current position also!
    my $first = $collection->first;
    my $last  = $collection->last;
    # get back an array-ref containing all items
    my $records = $collection->items_array_ref;
```

*Some options provided by "limit"*

In order to construct more complex restrictions the `"limit"` method may get called more than once, specifying one single condition with each call.

Every use of `"limit"` constructs either a *clause* or a *subclause*. A subclause is built either if the `"subclause"` attribute is used or a column is used repeatedly.

Every clause is built up by combining its subclauses (if any) using the `"entry_aggregator"` operator (whose default is *OR*) as a combining operator. Clauses are then `"AND"`ed together to yield the final restriction that is finally used to retrieve the records in question.

The `"operator"` (whose default is '=') can be any legal SQL operator like `"="`, `"<="`, `">="`, `"!="`, `"LIKE"`, `"IS"`, `"IS` `NOT"` as well as some convenience operators that silently use `"LIKE"` with properly set wildcards (`"MATCHES"`, `"STARTSWITH"` or `"ENDSWITH"`).

```
    # combining restrictions with "AND"
    # note that "AND" is implicit here unless a column name is repeated
    $collection->limit(column => 'col1', value => '...');
    $collection->limit(column => 'col2', value => '...');
    # combining restrictions with "OR"
    # note that the 'subclause' has the same value
    $collection->limit(column => 'col1', value => '...',
                       entry_aggregator => 'OR', # is already default
                       subclause => 'some_id');
    $collection->limit(column => 'col2', value => '...',
                       entry_aggregator => 'OR', # is already default
                       subclause => 'some_id');
```

For debugging purposes, you might want to examine the SQL statement generated behind the scene:

```
    warn $collection->build_select_query;
```

See Jifty::DBI::Collection about more ways or ordering and limiting collections.

### Action - Model relationship

When writing templates you often simply access some record from a model and want to operate on this very record by modifying it or you might want to add a new record of some type. To do this, our faithful Jifty::ClassLoader will create classes named `"MyApp::Action::CreateXxx"`, `"MyApp::Action::UpdateXxx"` or `"MyApp::Action::DeleteXxx"` for you. This enables you to write a template to operate on a single record like this:

```
    <%init>
    my $id = some_value_obtained_somehow;
    my $record = new MyApp::Model::Xxx;
    $record->load($id);
    my $action = Jifty->web->new_action(class   => 'UpdateXxx',
                                        moniker => 'mymoniker',
                                        record  => $record);
    </%init>
    ...
    <% $action->form_field('colname') %>
    ...
    <% Jifty->web->link(label  => 'Update',
                        submit => $action,
                        ... ) %>
```

The elegant thing around here is that you could write the class name of your action-class simply as `"UpdateXxx"` instead of the full package name `"MyApp::Action::UpdateXxx"` and there is no need to write a repeating update procedure for every record class that comes along. DRY - don't repeat yourself :-)

## SEE ALSO

Jifty::Record, Jifty::DBI::Record, Jifty::Collection, Jifty::DBI::Collection, Jifty::Manual::Actions, Jifty::Manual::Tutorial
