Jean-Philippe Doyle (j15e)

Developer, homebrewer & more

CakePHP ; Model without table

17 Mar 2008

Why do this? To validate data on a form that won't be stored in a database and still use both validation component and form helper.

Exemple : you want to create a form that allow users to share by email any article on your website.

1 - Model

class ArticleEmail extends AppModel {

    // Specify to not use a table
    var $useTable = false;

    // Specify your schema (instead of a table)
    var $_schema = array(
        'to_email' => array(
            'type' => 'string',
            'length' => 100),
        'message' => array(
            'type' => 'text'),
        'from_name' => array(
            'type' => 'string',
            'length' => 100),
        'from_email' => array(
            'type' => 'string',
            'length' => 100),
    );

    // Usual validations
    var $validate = array(
        'to_email' => array(
            'rule'=> VALID_EMAIL,
            'message'=> 'Email must be valid'
            ),
        'message' => VALID_NOT_EMPTY,
        'from_name' => VALID_NOT_EMPTY,
        'from_email' => array(
            'rule'=> VALID_EMAIL,
            'message'=> 'Email must be valid'
            ),
    );
}

2 - View

Same thing as if it was a database model (that's what you want).

3 - Controller

Specify to use the tableless model if you are using your model inside an other controller (here I am using ArticleEmail in my Article controller for the form that sends an article link to a user friend).

When you add models to a controller $uses, include the original model too :

var $uses = array('Article','ArticleEmail');

Instead of the usual "create/update" code :

$this->Article->create();
if ($this->Article->save($this->data)) {

You must use this one that won't try to save it to the database when all fields validates :

$this->ArticleEmail->create();
$this->ArticleEmail->data = $this->data;
if($this->ArticleEmail->validates()) {

Notice that you must set the data before using validates() as opposite to save() method.

You are done. Everything else will be done automatically as usual.