Steven smethurst Steven smethurst - 1 year ago 61
PHP Question

Cakephp Save with a table where the primary key is not 'id'

I have an existing web application that I am converting to use CakePHP.
The problem is that the primary keys for most of the tables are in this format "${table_name}_id" (story_id) instead of the CakePHP way of 'id'

When ever I try to update some of the fields for a row in the story table, the Save() function will return false. Is there any way of getting a more detailed error report from the Save() function. ?

When I set

Configure::write('debug', 2);
and check the SQL statements I do not see any UPDATE command, only SELECT statements.

I tried to edit the controller adding the following line to manually set the id field for the controller but it did not help.

$this->Story->id = $this->data['Story']['story_id'] ;

I'm running out of ideas. Any suggestions?

I have included the source code that I am using below

Story controller:

function admin_edit($id = null)
if (!$id && empty($this->data)) {
$this->Session->setFlash(__('Invalid '. Configure::read('') , true));

$this->layout = 'admin';
if (!empty($this->data)) {
if ($this->Story->save($this->data)) {
$this->Session->setFlash(__('The '. Configure::read('') .' has been saved', true));
} else {
$this->Session->setFlash(__('The '. Configure::read('') .' could not be saved. Please, try again.', true));

$this->data = $this->Story->read(null, $id );

Story model:

class Story extends AppModel {
var $name = 'Story';
var $primaryKey = 'story_id';

var $validate = array(
'author_id' => array('numeric'),
'title' => array('notempty'),
'story' => array('notempty'),
'genra' => array('notempty'),
'form' => array('notempty'),
'wordcount' => array('Please enter a number between 1 and 1000' => array(
'rule' => array('range', 1, 1001),
'message' => 'Please enter a number between 1 and 1000' ),
'Required' => array( 'rule' => 'numeric', 'required' => true )

//The Associations below have been created with all possible keys, those that are not needed can be removed
var $belongsTo = array(
'Author' => array(
'className' => 'Author',
'foreignKey' => 'author_id'

var $hasMany = array(
'UserNote' => array(
'className' => 'UserNote',
'foreignKey' => 'story_id',
'dependent' => false,
'conditions' => 'UserNote.notes != ""'

Story view:

echo $form->create('Story', array('action' => 'edit' ) );
echo $form->input('story_id',array('type'=>'hidden') );
echo $form->input('title');
echo $form->input('story');
echo $form->input('bio' );
echo $form->end('Update story details');?>

Story table

`story_id` int(11) NOT NULL AUTO_INCREMENT,
`closed` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`author_id` int(11) NOT NULL,
`title` varchar(255) NOT NULL,
`story` text NOT NULL,
`genra` varchar(255) NOT NULL,
`form` varchar(128) DEFAULT NULL,
`wordcount` varchar(255) NOT NULL,
`terms` varchar(255) NOT NULL DEFAULT '0',
`status` varchar(255) NOT NULL DEFAULT 'slush',
`published` date NOT NULL,
`payment` varchar(255) NOT NULL DEFAULT 'none',
`paypal_address` varchar(255) NOT NULL,
`resubmission` tinyint(1) NOT NULL DEFAULT '0',
`bio` text NOT NULL,
`password` varchar(255) NOT NULL DEFAULT 'yyggrrdd',
`comments` text NOT NULL,
PRIMARY KEY (`story_id`)

Answer Source

You should manually override the primary key field in the model (which is the right place to do this - the name of a primary key field is an attribute of the model, and not something that should be 'fudged' around in the controller.)

class Example extends AppModel {    var $primaryKey = 'example_id'; // example_id is the field name in the database}

The above code is from

While the suggestion to turn off validation will work, it's not the right way to go about it.

Lastly, if you're setting model variables within a controller, you use $this->Model->set('attributeName',value) rather than $this->Model->attributeName

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download