Model without table
It is one of those questions you hear often in the CakePHP channel: “How can I create a model without a table?” The answer is simple:
class ModelWithoutTable extends AppModel
{
var $useTable = false;
}
Related post: A controller without a model




Thanks cakebaker.
Maybe you should mention that by doing this you can still take advantage of all the cake’s inbuilt validations like VALID_NOT_EMPTY, VALID_EMAIL, etc…
-Mandy
using model without table i cool but is it possible to use phpCake without database ?
could we setup phpcake without db?
@sviktorov: Well, you don’t need a database to use CakePHP. If you use models, simply put var $useTable = false; into your AppModel, so that they don’t try to use a database.
HTH
Using models without corresponding tables in v1.2 makes FormHelper::create() throw up as it ‘automagically’ (I love this term) calls Model::schema().
The issued warning suggests overriding it with an own schema() function in the model. While this may be a solution in most cases, I can only make my schema() return a bogus array because which fields my ‘dynamic’ model has depends on many things. I have yet to find out any consequences of returning a bogus schema which does not correspond to the actual fields.
pfneuf - after taking a long walk at the sea shore I realized how fixated I was on always creating a form with a model. I came to the point were I thought about that poor other guy who wanted to create a form just to send an email WITHOUT saving the e-mail to the database (how foolish) …
But then -blam!- cake to the rescue! You can even create a form without a model!
This can be done by calling $form->create() with a nulled model name like this:
$form->create(null, array(’action’ => ‘myFunction’));
Seeing it written down this seems like trivia - and probably is, too. But after hours staring at the tempdocs nothing seemed obvious to me anymore. So I took off my clothes and took a walk down the shore. I wish everybody had a shore. And that it hadn’t been that cold. Dammit.
@ben: I am glad you found a solution. Another solution is to do it without the helper if there is too much magic.
But if you want to create a form that validates without connecting to a database, it still throws up the errors. Hrumph.
@Brad: Hm, I just tested it, and it works without any errors (I’m using the latest version from the repository). Here the code I used, first the model:
class Test extends AppModel { var $useTable = false; var $validate = array('test' => array('rule' => array('between', 2, 5), 'allowEmpty' => true)); }And here the controller action:
function index() { // $data['Test']['test'] = ‘12345′; // output: ok $data['Test']['test'] = ‘123456′; // output: nok $this->Test->set($data); if ($this->Test->validates()) { echo ‘ok’; } else { echo ‘nok’; } exit; }Hey all -
I tried using the example given, but I ran into another problem which I haven’t found a solution to yet: When you specify “var $useTable = false;” it seems you also remove your ability to call other models referenced in the $uses array.
Exhibit A -
class ModelWithoutTable extends AppModel {
var $name = ‘ModelWithoutTable ‘;
var $useTable = false;
var $uses = array(’ModelWithoutTable’,'TableModel’);
function get_info_from_other_model() {
return $this->TableModel->field(’id’,”name = ‘foo’”);
}
}
When $this->TableModel is encountered, Cake throws -
Notice: Undefined property: ModelWithoutTable::$TableModel
My reason for having this table-less model is so that I can have one model act as a manager for several other models. I need to access these other models using cake conventions.
Why not put this in a controller, you ask? I can’t do this because this manager functionality is needed by several different controllers throughout my site. The manager prepares data for interfacing with a third-party tool. I suppose I could make a parent controller class that other classes could be derived from, but really I just want to be able to call the manager class at whim. Also, I don’t think making the manager a Vendor class will work without some ugly hackery.
Anyway, I hope I was clear in my explanation and I would appreciate any feedback for solving this problem.
Cheers!
@Brian: var $uses is a controller feature, and hence it doesn’t work in the model (that’s the reason for the notice you get).
An idea of how it could be solved (I’m not sure I fully understood what you try to accomplish):
class ModelWithoutTable extends AppModel { var $useTable = false; var $TableModel = null; function __construct() { App::import('Model', 'TableModel'); $this->TableModel = new TableModel(); } function get_info_from_other_model() { return $this->TableModel->field(’id’,”name = ‘foo’”); } }Hope that helps!