cakephp/cakephp — pull request #1214 by shrimpwagon (2013-04-02 20:36:56+00:00)
Title: Not a Model object in getColumnType

Error when accessing a non-object method when trying to get the column type. This may be a rare instance and I can't exactly tell you how it all came about. I can't offer a more thorough solution due to my lack of knowledge of the deep inner workings of Cake's database methodology. I can however tell you a few things about how my code is constructed and what might be going on.

I have a model called `Task`. In this model there is a property called `tasks` which is assigned an empty array:

class Task extends AppModel {
...
public $tasks = array();
...
}

That right there may have something to do with Inflector but I'm just not sure.

Dumping the value of `$this->{$model}` in the `getColumnType` method shows an empty array, not an object, especially not a Task model object! This seems - is - the `tasks` property, understandably so. If `$model == 'tasks'` then `$this->{$model} == array()`

I am also connecting to a MSSQL server using Sqlserver driver. This is the production environment which has this issue. On my development environment I am just using good 'ol MySQL without this issue. Again, maybe something there, dunno.

So when I do `$this->save($somedata)` in the class I get this error:
> **Fatal error:** Call to a member function getColumnType() on a non-object in **.\lib\Cake\Model\Model.php** on line **1370**

So basically I see that in the `getColumnType` method that `$model` gets assigned `tasks` due to the `$column` explode split previously on line 1367 which was passed in a few functions back ultimately from `getDefaultConditions` in `_matchRecords` method line 1927 of DboSource.php.

Here is a backtrace right inside the `if` block after the condition in question:
> Model::getColumnType() - CORE\Cake\Model\Model.php, line 1370
DboSource::_parseKey() - CORE\Cake\Model\Datasource\DboSource.php, line 2565
DboSource::conditionKeysToString() - CORE\Cake\Model\Datasource\DboSource.php, line 2520
DboSource::conditions() - CORE\Cake\Model\Datasource\DboSource.php, line 2403
DboSource::_matchRecords() - CORE\Cake\Model\Datasource\DboSource.php, line 1931
DboSource::update() - CORE\Cake\Model\Datasource\DboSource.php, line 1835
Sqlserver::update() - CORE\Cake\Model\Datasource\Database\Sqlserver.php, line 371
Model::save() - CORE\Cake\Model\Model.php, line 1725
Task::startTask() - APP\Model\Task.php, line 73
TasksController::start() - APP\Controller\TasksController.php, line 12
ReflectionMethod::invokeArgs() - [internal], line ??
Controller::invokeAction() - CORE\Cake\Controller\Controller.php, line 486
Dispatcher::_invoke() - CORE\Cake\Routing\Dispatcher.php, line 187
Dispatcher::dispatch() - CORE\Cake\Routing\Dispatcher.php, line 162
require - APP\webroot\index.php, line 92
[main] - ROOT\index.php, line 42

Dumping the `$conditions` variable in `_matchRecords` method after its assignment in DboSource.php line 1931 show an array as:

['tasks.id'] => array(
)

Instead of:

['Tasks.id'] => array(
)

All in all, in my humble opinion I think using `is_object` instead of `isset` is actually more appropriate since the property MUST be an object for the `getColumnType` method to apply anyways.

Hope this helps.

Thanks,

shrimpwagon