Question

Using CakePHP 2.4.9 on a LAMP setup (Ubuntu 13.10, Apache 2, MySQL Server 5.5, PHP 5.5.3).

Trying to package a model (User) into a plugin but I have run into a strange problem:

In two different actions I use save() to either create or update a User. This works:

if ($this->request->data) {

    if ($this->User->create() && $this->User->save($this->request->data)) {
        $this->Session->setFlash(_('<strong>Congratulations!</strong> Successfully created a new user.'), 'default', array('class' => 'alert alert-success'));
        $this->redirect(array('action' => 'register'));
    } else {
        $this->Session->setFlash(_('<strong>Oops!</strong> Could not create a new user.'), 'default', array('class' => 'alert alert-danger'));
    }
}

But this doesn't work:

if ($this->request->data) {

    $this->User->id = $id;

    if ($this->User->save($this->request->data)) {
        $this->Session->setFlash(_('<strong>Congratulations!</strong> Successfully updated your user account.'), 'default', array('class' => 'alert alert-success'));
        $this->redirect(array('action' => 'settings'));
    } else {
        $this->Session->setFlash(_('<strong>Oops!</strong> Could not update user account.'), 'default', array('class' => 'alert alert-danger'));
    }
}

When I try to save the latter example (the "update action") it gives me the following error:

Fatal Error

Error: Call to a member function getColumnType() on a non-object File: /home/johan/sites/userplugin/lib/Cake/Model/Model.php Line: 1412

Notice: If you want to customize this error message, create app/View/Errors/fatal_error.ctp

The forms are pretty standard, I use the FormHelper to create form and fields. But in the update form I have a hidden field with the ID:

<?php echo $this->Form->hidden('id'); ?>

If I remove that, the update form goes through but creates a new object! So it's like $this->User->id = $id doesn't do anything. I currently set $id "manually", so $id = 1...

I tried searching for similar issues but didn't find anything. One discussion mentioned the ID field, maybe it's not correctly set up? But I couldn't find any solution in regards to that.

Was it helpful?

Solution 2

What I ultimately found out (and should've ruled out earlier, really) was that having an array defined in my AppModel, for configuring the plugin, named the same as my plugin was stupid, borderline retarded perhaps.

I.e. if your plugin is called MyPlugin, do not define a $myplugin array in your AppModel.

OTHER TIPS

There's a bad model reference

The different code permutations are not directly related to the problem - or may simply indicate another different problem =).

The line of code that is failing is this:

$this->{$model}->getColumnType($column);

Where $this is the User model instance. What that probably means is that when it fails, the object is not the class you expect to check simply do:

debug(get_class($this->User));

In your controller, it is most likely AppModel.

What causes this

A typical cause of that kind of "sometimes it works, sometimes it doesn't" problem is that there are some references to the model using the plugin prefix, and there are some that don't i.e.

<?php

App::uses('MyPluginAppModel', 'MyPlugin.Model');

class Group extends MyPluginAppModel {

    public $hasMany = array(
        'User' => array(
            'className' => 'User'
        ),
        #'User' # Or like this
    )

}

Whereas it should be like this:

<?php

App::uses('MyPluginAppModel', 'MyPlugin.Model');

class Group extends MyPluginAppModel {

    public $hasMany = array(
        'User' => array(
            'className' => 'MyPlugin.User'
        ),
        #'MyPlugin.User' # Or like this
    )

}

What happens here is it depends upon how the relevant model is first accessed, as to what populates the User key in the class registry and is returned for all subsequent requests for that model reference.

To fix the problem, ensure that the model is always referenced with the correct plugin prefix (or of course no prefix if it's not a plugin model).

try this

//Controller

public function edit(){ 

    if (!empty($this->request->data)) {

        //if you want to save on User object
         $this->User->id = $this->request->data['User']['id'];

        if ($this->User->save($this->request->data)) {
        .................................
            $this->Session->setFlash(_('<strong>Congratulations!</strong> Successfully updated your user account.'), 'default', array('class' => 'alert alert-success'));
            $this->redirect(array('action' => 'settings'));
        } else {
            $this->Session->setFlash(_('<strong>Oops!</strong> Could not update user account.'), 'default', array('class' => 'alert alert-danger'));
        }
    } else {
       $this->request->data = $this->User->read(null, $id);
    }
}

//edit view

<?php 
echo $this->Form->create('User'); 
echo $this->Form->hidden('id'); 
echo $this->Form->input('first_name'); 
..
..
.  
echo $this->Form->end(__('Save')); 
?>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top