2010-10-22 6 views
1

Bon, donc je suis assez nouveau à CakePHP. Ceci est la configuration:Passer les paramètres à travers le formulaire à contrôleur (CakePHP)

J'ai un modèle (Réservation), et un contrôleur, (ReservationController). J'essaie de fournir une simple fonctionnalité add().

L'URL de requête est: www.example.com/reservations/add/3

Où est l'ID de l'événement cette réservation est pour. Jusqu'ici, tout va bien. Le problème est, la forme est construite comme suit:

<h2>Add reservation</h2> 
<?php echo $form->create('Reservation'); 
echo $form->input('first_name'); 
echo $form->input('last_name'); 
echo $form->input('email'); 
echo $form->input('tickets_student'); echo $form->input('tickets_nstudent'); 
echo $form->end('Add');?> 

Lorsque je clique sur le bouton d'envoi, l'URL de la requête devient simplement www.example.com/reservations/add/, et l'ID d'événement est perdu.

Je l'ai résolu maintenant en saisissant l'identifiant dans le contrôleur, et le rendre disponible à la forme:

// make it available for the form 
$this->set('event_id', $eventid); 

Et puis, sous la forme:

$form->create('Reservation',array('url' => array($event_id))); 

Il fonctionne, mais ça me semble un peu moche. N'y a-t-il pas un moyen plus simple de s'assurer que l'action POST du formulaire est faite à l'url actuelle, au lieu de l'URL sans l'identifiant?

Répondre

6

Nik's answer échouera si le site Web n'est pas dans le serveur public_html root.

Cette réponse est plus solide:

<?php echo $form->create('Reservation',array('url'=>'/reservation/add/'.$data['id']));?> 
3

En suivant la convention la plus stricte pour un instant, lire une URL comme /reservations/add/3 serait, bien, confuse. Vous appelez le ReservationsController pour agir sur le modèle Reservation, mais en lui transmettant un ID d'événement. Appeler /reservations/edit/3 est beaucoup moins déroutant, mais tout aussi mauvais pour votre situation puisque la valeur id, "3", serait supposée être un identifiant de réservation. Essentiellement, vous faites au mieux une demande ambiguë. C'est un formulaire simple pour créer une réservation et cette réservation doit être associée à un événement. Dans un scénario «traditionnel», le formulaire permettrait à l'utilisateur de sélectionner un événement à partir d'une sorte de liste. Après tout, la clé étrangère, probablement event_id dans ce cas, est vraiment juste une autre propriété d'une réservation. La liste devrait être remplie dans le contrôleur; Cela se fait généralement via un appel .

Si vous connaissez déjà l'événement pour lequel vous voulez créer la réservation (ce que vous faites apparemment), alors je choisirais probablement la méthode analogue d'utiliser un champ caché dans le formulaire. Vous devez toujours définir la valeur dans le contrôleur comme vous le faites, mais le résultat final est un peu plus Cake-y. Le champ caché serait nommé data[Reservation][event_id] (encore une fois, je suppose que le nom de votre champ de clé étrangère).

+0

Je suis d'accord avec vous, parce que je suis en utilisant le même formulaire pour ajouter et modifier dans mes projets et ce sera source de confusion, mais si @Forceflow utilise deux actions distinctes, Je crois que ça ira, car il ne passera cette variable que dans l'action add. alors dans l'édition il connaîtra l'événement et il ne sera pas nécessaire d'être passé dans l'url. Mais il y en a trop dans nos hypothèses. :) –

1

Vous pouvez faire ce qui suit:

$form->create('Reservation',array('url' => $this->Html->url())); 

ainsi toutes vos variables de l'URL seront ajoutés dans l'action de forme :)

1

Comme le suggère Rob Wilkerson, la question est votre route URL n » t décrire avec précision l'opération en cours. Il devient plus déroutant lorsque vous souhaitez modifier la réservation: /reservations/edit/6. Maintenant, le numéro dans l'URL signifie quelque chose de différent.

La convention d'URL que j'utilise dans de telles situations (adaptée à votre cas particulier) est /events/3/reservations/add. Il faut un peu plus d'avance pour configurer vos itinéraires, mais j'ai trouvé que c'est supérieur pour la clarté sur la route.

Exemple routes.php:

Router::connect(
    '/events/:event_id/reservations/:action', 
    array('controller'=>'reservations','action'=>'index'), 
    array(
     'pass' => array('event_id'), // pass the event_id as a param to the action 
     'event_id' => '[0-9]+', 
     'actions'=>'add|index' // only reverse-routes with 'action'=>'add' or 
           // 'action'=>'index' will match this route 
    ) 
) 
// Usage: array('controller'=>'reservations','action'=>'add','event_id'=>3) 

Router::connect(
    '/events/:event_id/reservations/:id/:action', 
    array('controller'=>'reservations'), 
    array(
     'pass' => array('id'), // pass the reservation id as a param to the action 
     'id' => '[0-9]+', 
     'event_id' => '[0-9]+', 
     'actions'=>'edit|delete' // only reverse-routes with 'action'=>'edit' or 
           // 'action'=>'delete' will match this route 
    ) 
) 
// Usage: array('controller'=>'reservations','action'=>'edit','event_id'=>3,'id'=>6) 

Dans votre FormHelper::create appel, il vous faudrait préciser la plupart des route inverse que vous voulez suivre, mais encore une fois, le coût initial versera des dividendes à l'avenir . Il est généralement préférable d'être explicite avec Cake plutôt que d'espérer que son automagique fonctionne toujours correctement, d'autant plus que la complexité de votre application augmente.

1
$form->create('Reservation',array('action' => 'add',$eventId); 

et dans le contrôleur:

function add($eventId = null) 
    { 

      if($eventId == null) 
      { 
       // error state 
       throw new NotFoundException('Invalid id'); 
      } 

    ... 

    } 

je le fais tout le temps.

+1

Vous devriez corriger le bug d'évaluation vs d'affectation dans votre conditionnel. =) –

+0

merci - Je viens d'entrer du travail et n'ai aucune excuse réelle;) +1 – Leo

Questions connexes