CakePHP does not use my models
It's not possible to give a directly-working answer because: There's nothing wrong with the code in the question. That probably means you aren't running your own code at all.
Given that the only answer that can be given is advice, the only class that matters for the example in the question is Owner
.
Check filenames
The model conventions are:
The Model class OptionValue would be found in a file named OptionValue.php
Misnamed model files is by far the most common cause of "why is my model logic not being executed" questions. One pitfall is to add the suffix Model.php
to model files, is the model file named correctly?
In this case check that the file app/Model/Owner.php
exists.
Verify that the model is your model
If you're sure the model file is named correctly check what the app is using:
debug(get_class($this->Owner));
########## DEBUG ##########
'Owner'
###########################
If the output is "AppModel" - the model file is not loaded. There are very few reasons why CakePHP will not use a file that exists and one of them will apply:
- The file does not exist - there is a typo in the name
- The application is not looking in the same directory you are
- The application doesn't have permission to open the file
Verify the association exists
debug($this->Owner->hasMany);
########## DEBUG ##########
array(
'Car' => array(
'className' => 'Car',
'foreignKey' => 'owner_id',
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'dependent' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
)
###########################
If Car
is not in the output - the association isn't saved because to cake it doesn't exist - you'll need to identify why.
Check which files are loaded
If in doubt, check which files are loaded at run time:
debug(get_included_files());
########## DEBUG ##########
array(
...
...app/Model/Owner.php
...
)
###########################
This may indicate that a different file is being loaded, which prevents app/Model/Owner.php
from being loaded.
Use a test to verify what's happening
You can use a test case to aide debugging for example:
<?php
App::uses('Owner', 'Model');
class OwnerTest extends CakeTestCase {
public $fixtures = array(
'app.car',
'app.owner',
);
public function setUp() {
parent::setUp();
$this->Owner = ClassRegistry::init('Owner');
}
public function tearDown() {
unset($this->Owner);
parent::tearDown();
}
public function testCreate() {
$data = array(
'Owner' => array(
'name' => 'Me'
),
'Car' => array(
array(
'Car' => array(
'color' => 'red',
)
),
array(
'color' => 'blue',
)
)
);
$this->assertSame('Owner', get_class($this->Owner));
$this->Owner->getDatasource()->getLog();
$this->Owner->saveAssociated($data);
$log = $this->Owner->getDatasource()->getLog();
$expected = array();
$this->assertSame($expected, $log, 'Look ma, the sql log');
}
}
Which should output:
-> Console/cake test Test/Case/Model/OwnerTest.php
Welcome to CakePHP v2.4.5 Console
---------------------------------------------------------------
App : app
Path: /var/www/files.dev/htdocs/app/
---------------------------------------------------------------
CakePHP Test Shell
---------------------------------------------------------------
PHPUnit 3.7.24 by Sebastian Bergmann.
F
Time: 169 ms, Memory: 9.00Mb
There was 1 failure:
1) OwnerTest::testCreate
Look ma, the sql log
Failed asserting that Array (
'log' => Array (
0 => Array (
'query' => 'BEGIN'
'params' => Array ()
'affected' => null
'numRows' => null
'took' => null
)
1 => Array (
'query' => 'INSERT INTO `test_database_name`.`owners` (`name`) VALUES ('Me')'
'params' => Array ()
'affected' => 1
'numRows' => 1
'took' => 0.0
)
2 => Array (
'query' => 'INSERT INTO `test_database_name`.`cars` (`color`, `owner_id`) VALUES ('red', 1)'
'params' => Array ()
'affected' => 1
'numRows' => 1
'took' => 0.0
)
3 => Array (
'query' => 'INSERT INTO `test_database_name`.`cars` (`color`, `owner_id`) VALUES ('blue', 1)'
'params' => Array ()
'affected' => 1
'numRows' => 1
'took' => 0.0
)
4 => Array (
'query' => 'COMMIT'
'params' => Array ()
'affected' => 1
'numRows' => 1
'took' => 0.0
)
)
'count' => 9
'time' => 0.0
) is identical to Array ().
FAILURES!
Tests: 1, Assertions: 2, Failures: 1.
$
Note that correctly one owner was created for "Me", and two cars - each linked to the owner record for "Me".
CakePHP does not use my models
It's not possible to give a directly-working answer because: There's nothing wrong with the code in the question. That probably means you aren't running your own code at all.
Given that the only answer that can be given is advice, the only class that matters for the example in the question is Owner
.
Check filenames
The model conventions are:
The Model class OptionValue would be found in a file named OptionValue.php
Misnamed model files is by far the most common cause of "why is my model logic not being executed" questions. One pitfall is to add the suffix Model.php
to model files, is the model file named correctly?
In this case check that the file app/Model/Owner.php
exists.
Verify that the model is your model
If you're sure the model file is named correctly check what the app is using:
debug(get_class($this->Owner));
########## DEBUG ##########
'Owner'
###########################
If the output is "AppModel" - the model file is not loaded. There are very few reasons why CakePHP will not use a file that exists and one of them will apply:
- The file does not exist - there is a typo in the name
- The application is not looking in the same directory you are
- The application doesn't have permission to open the file
Verify the association exists
debug($this->Owner->hasMany);
########## DEBUG ##########
array(
'Car' => array(
'className' => 'Car',
'foreignKey' => 'owner_id',
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'dependent' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
)
###########################
If Car
is not in the output - the association isn't saved because to cake it doesn't exist - you'll need to identify why.
Check which files are loaded
If in doubt, check which files are loaded at run time:
debug(get_included_files());
########## DEBUG ##########
array(
...
...app/Model/Owner.php
...
)
###########################
This may indicate that a different file is being loaded, which prevents app/Model/Owner.php
from being loaded.
Use a test to verify what's happening
You can use a test case to aide debugging for example:
<?php
App::uses('Owner', 'Model');
class OwnerTest extends CakeTestCase {
public $fixtures = array(
'app.car',
'app.owner',
);
public function setUp() {
parent::setUp();
$this->Owner = ClassRegistry::init('Owner');
}
public function tearDown() {
unset($this->Owner);
parent::tearDown();
}
public function testCreate() {
$data = array(
'Owner' => array(
'name' => 'Me'
),
'Car' => array(
array(
'Car' => array(
'color' => 'red',
)
),
array(
'color' => 'blue',
)
)
);
$this->assertSame('Owner', get_class($this->Owner));
$this->Owner->getDatasource()->getLog();
$this->Owner->saveAssociated($data);
$log = $this->Owner->getDatasource()->getLog();
$expected = array();
$this->assertSame($expected, $log, 'Look ma, the sql log');
}
}
Which should output:
-> Console/cake test Test/Case/Model/OwnerTest.php
Welcome to CakePHP v2.4.5 Console
---------------------------------------------------------------
App : app
Path: /var/www/files.dev/htdocs/app/
---------------------------------------------------------------
CakePHP Test Shell
---------------------------------------------------------------
PHPUnit 3.7.24 by Sebastian Bergmann.
F
Time: 169 ms, Memory: 9.00Mb
There was 1 failure:
1) OwnerTest::testCreate
Look ma, the sql log
Failed asserting that Array (
'log' => Array (
0 => Array (
'query' => 'BEGIN'
'params' => Array ()
'affected' => null
'numRows' => null
'took' => null
)
1 => Array (
'query' => 'INSERT INTO `test_database_name`.`owners` (`name`) VALUES ('Me')'
'params' => Array ()
'affected' => 1
'numRows' => 1
'took' => 0.0
)
2 => Array (
'query' => 'INSERT INTO `test_database_name`.`cars` (`color`, `owner_id`) VALUES ('red', 1)'
'params' => Array ()
'affected' => 1
'numRows' => 1
'took' => 0.0
)
3 => Array (
'query' => 'INSERT INTO `test_database_name`.`cars` (`color`, `owner_id`) VALUES ('blue', 1)'
'params' => Array ()
'affected' => 1
'numRows' => 1
'took' => 0.0
)
4 => Array (
'query' => 'COMMIT'
'params' => Array ()
'affected' => 1
'numRows' => 1
'took' => 0.0
)
)
'count' => 9
'time' => 0.0
) is identical to Array ().
FAILURES!
Tests: 1, Assertions: 2, Failures: 1.
$
Note that correctly one owner was created for "Me", and two cars - each linked to the owner record for "Me".
Cakephp model not working
Is your Model file name is Vehicle.php or vehicle.php ?
If it is lowercase that mean your model is generating on fly and cant read useTable from file because it is not using that file.
Also can you show your table primary key ? If it is not 'id' you must specify it with this code.
public $primaryKey = 'example_id';
CakePHP $belongsTo not working
possible duplicate of CakePHP does not save associated Models. see This is by far the most common cause of "why is my model logic not being executed" questions.
It was the file names, some of them where the plural form vs. singular. I changed Events.php to Event.php and Companies.php to Company.php that seemed to do the trick.
How to use models without database on CakePHP and have associations?
I would suggest using ArraySource
from the community-maintained CakePHP Datasources plugin:
- CakePHP 1.3.x - see
master
branch - CakePHP 2.x - see
2.0
branch
Download the entire plugin and extract the contents to app/plugins/datasources
.
Define a connection to the datasource in app/config/database.php
:
public $array = array('datasource' => 'Datasources.array');
This should allow you to emulate a table by defining records in your model:
class Country extends AppModel {
public $useDbConfig = 'array';
public $records = array(
array('id' => 1, 'name' => 'Test record')
);
}
cakephp: how to use find statements in models instead of controller
The answers which have been given answer part of your question. You can use the find method without the Model class declaration (so $this->find()
instead of $this->Model->find()
).
To adhere to the "fat models, skinny controllers" principle, your models should hold most of the business logic of your application, while the controllers handle the data from the model that's used by your views.
So, if you want to have all the find
logic happening in your models, you should do the following.
Product.php:
<?php
class ProductModel extends AppModel {
//Associations, etc. go here
function getProducts($limit=5) {
$products = array();
$products = $this->find('all', array('limit' => $limit));
return $products;
}
}
?>
Note that you cannot use $this->set()
in your model, you should use it in your controller:
ProductsController.php:
<?php
class ProductsController extends AppController {
//Components, helpers, etc. go here
function index() {
$products = $this->Product->getProducts(10);
$this->set('products', $products);
}
}
?>
A populated $products
variable (if there are records in the revelant database table) will now be available in you view.
This is a great article detailing the concepts of Cake and there's another one in the Cookbook on MVC in general.
Related Topics
Get Numbers from String with PHP
Passing JavaScript Variable to PHP Using Ajax
Get Next and Previous Day with PHP
Get Nearest Places on Google Maps, Using MySQL Spatial Data
How to Detect Country/Location of Visitor
Nginx Redirect Loop, Remove Index.PHP from Url
The Csrf Token Is Invalid. Please Try to Resubmit the Form
Curl and Ping - How to Check Whether a Website Is Either Up or Down
How to Get Common Values from Two Different Arrays in PHP
Using Like in Bindparam for a MySQL Pdo Query
PHP Simplexml: Insert Node at Certain Position
Detect Clients with Proxy Servers via PHP
Merge 'With' and 'Wherehas' in Laravel 5