CatalystX::CRUD::Model - base class for CRUD models


 package MyApp::Model::Foo;
 use base qw( CatalystX::CRUD::Model );
                    object_class    => 'MyApp::Foo',
                    page_size       => 50,
 # must define the following methods
 sub new_object         { }
 sub fetch              { }
 sub search             { }
 sub iterator           { }
 sub count              { }
 sub search_related     { }
 sub iterator_related   { }
 sub count_related      { }


CatalystX::CRUD::Model provides a high-level API for writing Model classes. CatalystX::CRUD::Model methods typically return CatalystX::CRUD::Object objects.

This documentation is intended for Model developers.


You may configure your CXCM-derived Models in the usual way (see the Catalyst Manual).

If the object_class key/value pair is set at initialization time, the value will be stored in the object_class() accessor. This feature is intended as a convenience for setting the name of the CatalystX::CRUD::Object class to which your CatalystX::CRUD::Model acts as an interface.


CatalystX::CRUD::Model inherits from Catalyst::Component::ACCEPT_CONTEXT and Catalyst::Model. New and overridden methods are documented here.


This accessor is available via Catalyst::Component::ACCEPT_CONTEXT and returns the $c value for the current request.

This method is not implemented at the CatalystX::CRUD::Model level but is highlighted here in order to remind developers that it exists.


The object_class() accessor is defined for your convenience. It is set by the default Xsetup() method if a key called object_class is present in config() at initialization time.


Overrides the Catalyst::Model new() method to call Xsetup().


Called by new() at application startup time. Override this method in order to set up your model in whatever way you require.

Xsetup() is called by new(), which in turn is called by COMPONENT(). Keep that order in mind when overriding Xsetup(), notably that config() has already been merged by the time Xsetup() is called.


Returns the page_size set in config().


Returns CatalystX::CRUD::Object->new(). A sane default, assuming object_class is set in config(), is implemented in this base class.


CXCM subclasses need to implement at least the following methods:

fetch( args )

Should return the equivalent of CatalystX::CRUD::Object->new( args )->read().

search( query )

Returns zero or more CXCO instances as an array or arrayref. query may be the return value of make_query().

iterator( query )

Like search() but returns an iterator conforming to the CatalystX::CRUD::Iterator API.

count( query )

Like search() but returns an integer.

search_related( obj, relationship )

Returns zero or more CXCO instances like search(). The instances are related to obj via relationship.

iterator_related( obj, relationship )

Like search_related() but returns an iterator.

count_related( obj, relationship )

Like search_related() but returns an integer.


Catalyst components accessing CXCM instances may need to access model-specific logic without necessarily knowing what kind of model they are accessing. An example would be a Controller that wants to remain agnostic about the kind of data storage a particular model implements, but also needs to create a model-specific query based on request parameters.

 $c->model('Foo')->search(@arg);  # @arg depends upon what Foo is

To support this high level of abstraction, CXCM classes may implement the following optional methods.


Should return appropriate values for passing to search(), iterator() and count(). Example of use:

 # in a CXCM subclass called MyApp::Model::Foo
 sub search {
     my $self = shift;
     my @arg  = @_;
     unless(@arg) {
         @arg = $self->make_query;
     # search code here
     return $results;
 sub make_query {
     my $self = shift;
     my $c    = $self->context;
     # use $c->req to get at params() etc.
     # and create a query
     return $query;
 # elsewhere in a controller
 my $results = $c->model('Foo')->search;  # notice no @arg necessary since 
                                          # it will default to 
                                          # $c->model('Foo')->make_query()
add_related( obj, rel_name, foreign_value )

Associate foreign object identified by foreign_value with obj via the relationship rel_name.

It is up to the subclass to implement this method.

rm_related( obj, rel_name, foreign_value )

Dissociate foreign object identified by foreign_value from obj via the relationship rel_name.

It is up to the subclass to implement this method.

put_related( obj, rel_name, foreign_value )

Create new related foreign object. Unlike add_related(), the foreign object need not already exist. put_related() should be idempotent.

remove_related() is an alias for rm_related().

find_related( obj, rel_name, foreign_value )

Return related object for foreign_value based on rel_name for obj.

has_relationship( obj, rel_name )

Should return true or false as to whether rel_name exists for obj.

It is up to the subclass to implement this method.


Peter Karman, <perl at>


Please report any bugs or feature requests to bug-catalystx-crud at, or through the web interface at I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.


You can find documentation for this module with the perldoc command.

    perldoc CatalystX::CRUD

You can also look for information at:


Copyright 2007 Peter Karman, all rights reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.