phpcakephpinflector

CakePHP Call to a member function save() on a non-object


Let's start with a simplified version my code:

Model: Sku.php

class Sku extends AppModel {

}

Controller: SkusController.php

class SkusController extends AppController {

    public function admin_add() {

        $this->layout = 'admin';

        if($this->request->is('post')) {
            if($this->Sku->save($this->request->data)) {
                // Do stuff
            }
            else // Do stuff
        }

    }

}

View: Skus > admin_add.ctp

<?php echo $this->Form->create('Sku', array('type'=>'file')); ?>
<?php echo $this->Form->input('Sku.item_no')); ?>
<?php echo $this->Form->input('Sku.size'); ?>
<?php echo $this->Form->input('Sku.color'); ?>
<button type="submit">Save SKU</button>
<?php echo $this->Form->end(); ?>

When I submit the form I get the error Call to a member function save() on a non-object. At the beginning of my controller file if I add the following everything works fine and a new row is inserted into the skus table.

public $uses = 'Sku';

If I have used all the proper naming conventions shouldn't I be able to omit the previous line? Furthermore, If I change all of the file and class names to Test following the same naming conventions it works without the $uses variable. This leads me to believe I have some sort of conflict elsewhere in my code. Any suggestions as to why this may be happening or where to look for a potential problem?

Thanks in advance!


Solution

  • Edit: Looks like the inflector cant turn the plural to singular: http://dogmatic69.com/inflector/Skus. So either you have to go with $uses or you add the rule to the inflector. See the inflector configuration.

    You're not using an array or boolean for the Controller::$uses property.

    public $uses = 'Sku';
    

    Should be:

    public $uses = array('Sku');
    

    Actually you don't have to define it at all if the the controller and model match the conventions.

    Read the documention http://api.cakephp.org/2.4/class-Controller.html#$uses

    $uses An array containing the class names of models this controller uses.

    Example: public $uses = array('Product', 'Post', 'Comment');

    Can be set to several values to express different options:

    • true Use the default inflected model name.
    • array() Use only models defined in the parent class.
    • false Use no models at all, do not merge with parent class either.
    • array('Post', 'Comment') Use only the Post and Comment models. Models Will also be merged with the parent class.

    The default value is true.