Reputation: 165
I am trying to get my CakePHP app to use slugs instead of ids. I have read several tutorials and the CakePHP book about it, but I must be missing something simple.
My table has a "slug" field that I want to use for the URL instead of the default id.
I changed my ItemsController view to this:
public function view($slug = null) {
if (!$this->Item->exists($slug)) {
throw new NotFoundException(__('Invalid item'));
}
$this->set('item', $this->Item->findBySlug($slug));
}
And added this to my routes.php
Router::connect(
'/items/:slug',
array('controller' => 'items', 'action'=>'view'),
array('pass'=>array('slug'))
);
Yet I still get "Invalid Item, requested address not found..." when going to:
mycakeapp/items/slug-value
However, if I change everything from 'slug' to 'id' then the URL:
mycakeapp/items/id-value
works just fine
Can someone help me? Thanks in advance.
Upvotes: 0
Views: 964
Reputation: 25698
Well, read the documentation for Model::exists().
Returns true if a record with particular ID exists.
If $id is not passed it calls Model::getID() to obtain the current record ID, and then performs a Model::find('count') on the currently configured datasource to ascertain the existence of the record in persistent storage.
It expects an id not a slug.
Here is a proper example from a model method to display an artist:
public function view($id = null, $options = array()) {
$defaults = array(
'contain' => array(
/* ... */
),
'conditions' => array(
'OR' => array(
$this->alias . '.' . $this->primaryKey => $id,
$this->alias . '.slug' => $id
)
)
);
$artist = $this->find('first', Hash::merge($defaults, $options));
if (empty($artist)) {
throw new NotFoundException(__('Invalid Artist'));
}
return $artist;
}
The controllers try/catches the exception and sets the exception message to the session by calling Session->setFlasH(). Easy. :)
Upvotes: 3