Question

I am trying to create my first Lithium app and I'm getting a very odd error.

I have a line in my index view,

<td><?php echo $this->html->link($question->title, array('controller'=>'questions','action'=>'view','id'=>$question->id)); ?></td>

Which I would imagine would link to that records view, and using 'questions/view'.$question->id' it does, however, using an array url I get a fatal.

Fatal error: Uncaught exception 'lithium\net\http\RoutingException' with message 'No parameter match found for URL('controller' => 'questions', 'action' => 'view', 'id' => '1').' in /Applications/MAMP/htdocs/learning-lithium/libraries/lithium/net/http/Router.php on line 306

Which to me looks like the router is trying to match the url in the helper, and as it can't, for some reason, it's throwing an exception. Does anyone have any idea's why this is? I'm attacking Lithium from a CakePHP standpoint, so this seems odd to me.

Was it helpful?

Solution

The 'args' param is handled by the default routes and get passed in as arguments to your action method.

Try this:

<?=$this->html->link($question->title, array('Questions::view', 'args' => array($question->id))); ?>

To route it with an id param, you need to specify a route that looks for an id param via {:id}. Look in the default routes.php file for the "Database object routes" section. That has some examples which I'll copy below for completeness:

/**
 * ### Database object routes
 *
 * The routes below are used primarily for accessing database objects, where `{:id}` corresponds to
 * the primary key of the database object, and can be accessed in the controller as
 * `$this->request->id`.
 *
 * If you're using a relational database, such as MySQL, SQLite or Postgres, where the primary key
 * is an integer, uncomment the routes below to enable URLs like `/posts/edit/1138`,
 * `/posts/view/1138.json`, etc.
 */
// Router::connect('/{:controller}/{:action}/{:id:\d+}.{:type}', array('id' => null));
// Router::connect('/{:controller}/{:action}/{:id:\d+}');

/**
 * If you're using a document-oriented database, such as CouchDB or MongoDB, or another type of
 * database which uses 24-character hexidecimal values as primary keys, uncomment the routes below.
 */
// Router::connect('/{:controller}/{:action}/{:id:[0-9a-f]{24}}.{:type}', array('id' => null));
// Router::connect('/{:controller}/{:action}/{:id:[0-9a-f]{24}}');

So you would need to uncomment one of those two sections depending on what format your ids take. They use regular expressions with the id param to make sure it doesn't match url arguments that aren't ids. Incidentally, the first route is setting the default value for id to null which doesn't exactly make sense to me because I don't think the route will ever match with a null value, but anyway, that is how you set default values for your params.

Note that if you do this, your controller action method needs to look like this:

public function view() {
    $id = $this->request->id;
    // or an alternative that does the same thing
    // $id = $this->request->get("params::id");
    // ... etc ...
}

The only way to get url pieces passed in as arguments to your controller action method is to use the 'args' param.

OTHER TIPS

You're not using named parameters in your route, so just output the following in your view:

<?php echo $this->html->link($question->title, array('controller'=>'questions', 'action'=>'view', $question->id));?>

Your function signature in QuestionsController should simply be:

public function view($id) {}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top