Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
Jifty::Manual::Models(User Contributed Perl DocumentatJifty::Manual::Models(3)

       Jifty::Manual::Models - Managing	your datastore

       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::ModelNameCollection 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.


       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:

       o correctly type	your data inside the data-store

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

       o tell Jifty the	behaviour in terms of form display

       o 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


       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
       o 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.

       o 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.

       o 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.

       o Jifty::DBI::Record

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

       o 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.

       o 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.

       o Jifty::Collection

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

       o 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

	   # 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

       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'

	   # 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

	   # 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


	   # 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

       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

   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:

	   my $id = some_value_obtained_somehow;
	   my $record =	new MyApp::Model::Xxx;

	   my $action =	Jifty->web->new_action(class   => 'UpdateXxx',
					       moniker => 'mymoniker',
					       record  => $record);
	   <% $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 :-)

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

perl v5.32.0			  2015-04-30	      Jifty::Manual::Models(3)


Want to link to this manual page? Use this URL:

home | help