tags:

views:

510

answers:

4

I have the following Model and Controller files, and when i visit this url, http://....../pois/index i get this error:

Notice (8): Undefined property: PoisController::$Poi [APP/controllers/pois_controller.php, line 5]

Fatal error: Call to a member function find() on a non-object in /home/joecoyle/public_html/app/controllers/pois_controller.php on line 5

The Model is this, called poi.php:

<?php
class Poi extends AppModel {

}
?>

And the controller is this, named pois_controller.php

<?php
class PoisController extends AppController {

    function index(){
            $this->set('pois',$this->Poi->find('all'));
    }
}
?>

As i am new to CakePHP i am not sure what is causing this error, as everything seems to be named, right, and i am following the tutorial on the CakePHP site...

Thanks

A: 

It's a problem because $this->Poi has not been initialized as an object. I'm not familiar with CakePHP, but in your init function in the PoisController or in contructor you should call $this->Poi = new Poi(); so in the index action when you try to call find(), the method will be called on an instance of Poi model.

Bogdan Constantinescu
According to the CakePHP tutorial, it's not necessary to do that, as its handled automatically. The blog example on the tutorial works for me, but this doesnt, even though all that has changed is the name. thanks.
joec
Have you checked your include path? If CakePHP uses an autoloader you should provide the path where to look for your modules. I'm not sure how CakePHP does it, but at the moment your model isn't initialized.
Bogdan Constantinescu
I have another Model and Controller called Category which works as expected, in the same directory, so include paths shouldnt be a problem.
joec
Isn't your Controller supposed to look like this? `class PoisController extends AppController {var $name = 'Poi'; (...)`
Bogdan Constantinescu
thats optional i believe to deal with php4, but im using php5
joec
+2  A: 

You need add var $name = "Poi"; to initialize your class in the controller.

And I've tested that in PHP5.It seems that this is necessary.

Edit: controller file name:pois_controller.php,code:

 <?php
 class PoisController extends AppController
 {
       var $name = "Poi";
       function index()
       {
           debug($this->Poi);
           exit;
       }
 }
 ?>

database name:pois.Structure:id ,name

And using /pois/ will got:

Poi Object
(
[name] => Poi
[useDbConfig] => default
[useTable] => pois
[displayField] => name
[id] => 
[data] => Array
    (
    )

[table] => pois
[primaryKey] => id
[_schema] => Array
    (
        [id] => Array
            (
                [type] => integer
                [null] => 
                [default] => 
                [length] => 11
                [key] => primary
            )

        [name] => Array
            (
                [type] => integer
                [null] => 
                [default] => 
                [length] => 11
            )
   ...etc
SpawnCxy
were you able to test it with the name `Poi`?
joec
yeah,that's right.
SpawnCxy
Its not working for me? What names did you have for controller / model / database table/ view?
joec
..well,see update.
SpawnCxy
model is not necessary.
SpawnCxy
+1  A: 

If SpawnCxy's solution doesn't do the job (my own controllers set the name property to the pluralized version rather than the singular variation that the model takes), take a look at the inflection. "Poi" isn't a "common" word and a quick test tells me that CakePHP 1.2.6 doesn't handle this word the way you're thinking it will:

echo '<p>' . Inflector::singularize( 'Pois' ) . '</p>'; # prints "Pois"
echo '<p>' . Inflector::pluralize( 'Poi' ) . '</p>';    # prints "Pois"

The point of this, of course, is that Cake may not be making the correct association between the PoisController (plural) and the Poi model (singular) the way it does for most common English names.

Rob Wilkerson
Ah, that explains a lot - Poi is an acronym for Point of Interest - i thought i could save myself some typing, however, if i was to use PointOfInterest instead, what would the Model / Controller names be? This plural stuff is really confusing... thanks.
joec
Eeks. I've never been a fan of acronyms in my models since they're supposed to reference a "thing". I might just call it `Location` (with a `LocationsController`) or something else a bit more friendly to the convention. As I mentioned above, though, you can customize your inflections by telling Cake how to inflect a given name.
Rob Wilkerson
FWIW, I suspect that the plural of `PointOfInterest` would be `PointOfInterests` as far as Cake is concerned, but you can copy the code above and test easily enough. I didn't try it out.
Rob Wilkerson
A: 

An alternative to adapting your code to Cake's pluralising/singularising rules is the converse: adapting Cake's rules to your code:

In app/config/inflections.php, find the $irregularPlural line, and change it to:

$irregularPlural = array('poi'=>'pois');

This will instruct Cake to treat the singular of "Pois" as "Poi."

This is a good choice when changing the inflection rules creates better readability/comprehensibility of the rest of your code. For example, by default, Cake treats the singular of "News" as "New". However, it made more sense to find news items with $this->News->find than $this->New->find, so I tweaked the inflection rules.

Daniel Wright
For the sake of argument, I changed the inflection rules as you suggested, and also happened to forget to change my database table. This popped up the CakePHP message - `database table 'pois' missing for Model 'Pois'`. The database table it suggests is correct (plural), but its still treating my model as plural even though the model should be singular... which it is `class Poi extends AppModel`.
joec