Reputation: 31
I cannot create a proper url using the URL view-helper when parent and child route have common/same params.
my url config:
'contact' => array(
'type' => 'Segment',
'options' => array(
'route' => '/contact[/:contact][/action/:action]',
'constraints' => array(
'contact' => '[0-9]+',
'action' => '[a-zA-Z_-]+',
),
'defaults' => array(
'controller' => 'CrmContact',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'task' => array(
'type' => 'Segment',
'options' => array(
'route' => '/task[/:task][/action/:action]',
'constraints' => array(
'task' => '[0-9]+',
'action' => '[a-zA-Z_-]+',
),
'defaults' => array(
'controller' => 'CrmTask',
'action' => 'index',
),
),
),
)
)
As it is obvious both parent and child routes contain the param "action", this route works perfectly fine when called upon directly meaning if you hit the browser with '/contact/1/task/1/action/edit' all is god. The problems arise when trying to construct this url using the viewhelper Url
$this->url('contact/task', array('contact' => $contact->id,'task' => $task->id, 'action' => 'edit'))
This produces the wrong url though, namely
/contact/1/action/edit/task/1 instead of
/contact/1/task/1/action/edit
the helper basically hijacks the action param from the child route and uses it for the parent route... I cannot stop using the param 'action' since it is part of the frameworks way of routing request across the controllers methods....
Upvotes: 1
Views: 773
Reputation: 31
The reason I want to keep "task" as child route of "contact" is because task makes sense only under contact, it's basically a many-to-one relation. I resolved it by breaking it in more child routes:
'contact' => array(
'type' => 'Segment',
'options' => array(
'route' => '/contact[/:contact]',
'constraints' => array(
'contact' => '[0-9]+',
),
'defaults' => array(
'controller' => 'CrmContact',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'contact_action' => array(
'type' => 'Segment',
'options' => array(
'route' => '/action/:action',
'constraints' => array(
'contact' => '[0-9]+',
'action' => '[a-zA-Z_-]+',
),
'defaults' => array(
'controller' => 'CrmContact',
'action' => 'index',
),
),
),
'task' => array(
'type' => 'Segment',
'options' => array(
'route' => '/task[/:task]/action/:action',
'constraints' => array(
'task' => '[0-9]+',
'action' => '[a-zA-Z_-]+',
),
'defaults' => array(
'controller' => 'CrmTask',
'action' => 'index',
),
),
),
)
),
Upvotes: 1
Reputation: 565
Your route contact and your child route task are associated with different controllers. So you can separate them like this.
'contact' => array(
'type' => 'Segment',
'options' => array(
'route' => '/contact[/:contact][/action/:action]',
'constraints' => array(
'contact' => '[0-9]+',
'action' => '[a-zA-Z_-]+',
),
'defaults' => array(
'controller' => 'crm-contact',
'action' => 'index',
),
),
),
'task' => array(
'type' => 'Segment',
'options' => array(
'route' => '/task[/:task][/action/:action]',
'constraints' => array(
'task' => '[0-9]+',
'action' => '[a-zA-Z_-]+',
),
'defaults' => array(
'controller' => 'crm-task',
'action' => 'index',
),
),
),
Also the default routes are controller/action. So separate controllers are usually in separate routes.
If you need to have your contact id in your task route you can change the route to
'route' => 'contact/:contact/task[/:task][/action/:action]',
Also you can rename task and contact constraints as task_id and contact_id for clarity.
Upvotes: 1