Pergunta

How do you set up routing to view data via a field other than the ID in CakePHP? I'm trying to view my users via /username/'username' in CakePHP 2.4.

So far, I have this in my routes.php, however I can't figure out how to pass the username to my Users controller and use that instead of an ID if needs be.

Router::connect(
    '/username/:username',
    array('controller' => 'users', 'action' => 'view'),
    array(
        'pass' => array('username')
    )
);

And my controller function, I have this, which throws a Fatal error: Call to undefined function findByUsername():

public function view($id = null, $username = null) {

    if ($user = $this->User-findByUsername($username)) {
        $this->set('user', $user);
    } elseif ($user != $this->User-findByUsername($username)) {
        throw new NotFoundException(__('Invalid user'));
    } else {
        if (!$this->User->exists($id)) {
            throw new NotFoundException(__('Invalid user'));
        }
        $options = array('conditions' => array('User.' . $this->User->primaryKey => $id));
        $this->set('user', $this->User->find('first', $options));
    }
}
Foi útil?

Solução

First solution

Don't do anything with routers. They are just fine as they are in default CakePHP package. There were couple of syntax errors in your code. This should work when called either

"app/controller/view/-/username"

or

"app/controller/view/id"

Controller action code itself like this

<?php
 public function view($id, $username = null) {
    if(!is_null($username)) {
      if($user = $this->User->findByUsername($username))
          $this->set('user', $user);
      elseif (count($this->User->findByUsername($username)) == 0)
          throw new NotFoundException(__('Invalid user'));
    }
    else {
        if($id == '-') || !$this->User->exists($id))
            throw new NotFoundException(__('Invalid user'));
        else {
            $options = array('conditions' => array("User.{$this->User->primaryKey}" => $id));
            $this->set('user', $this->User->find('first', $options));
        }
    }
 }
?>

Second solution

With only one parameter this could be done like this (personally I don't like this, it breaks straightforwardness of Cake-style to do it). Call this like this:

"app/controller/view/username"

or

"app/controller/view/id"

And controller action code itself:

<?php
 public function view($param) {
    if(!is_numeric($param))) { // $param is not numeric => it is username
      if($user = $this->User->findByUsername($param))
          $this->set('user', $user);
      elseif (count($this->User->findByUsername($param)) == 0)
          throw new NotFoundException(__('Invalid user'));
    }
    else { // $param is numeric => it is id
        if(!$this->User->exists($param))
            throw new NotFoundException(__('Invalid user'));
        else {
            $options = array('conditions' => array("User.{$this->User->primaryKey}" => $param));
            $this->set('user', $this->User->find('first', $options));
        }
    }
 }
?>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top