CakePHP - Controller or No Controller?

2019-09-09 15:27发布

问题:

I am currently building a web app which has two models, Donor and Donation Models respectively. It has multiple user roles. When the staff user first registers a donor, I want him to be redirected to another form which allows him to fill in the Donation details(the donor is registered once the first donation is successful).

Firs of all, should I create a donation controller, from which I would redirect the user using:

return $this->redirect(array('controller'=>'donations','action'=>'add'));

For the above to work, it requires me to save the newly registered donor's id in a session like so :

$this->Session->write('id', $this->Donor->id);

So the user is redirected to 'donations/add' in the url, and this works fine.. However I think this has some flaws. I was wandering whether I should create another action inside the Donor controller called 'add_donation', which will have its respective 'View'. The idea is to be able to form a url of the sort : 'donors/add_donation/4' (4 being the donor_id ! ) This URL follows this construct: 'controller/action/id'

If anyone could shed some light on best practices, or describe any caveats to my solution(the former, using session etc.) , please do help a brother out! Ill be deeply indebted to you! Thanks in advance!

回答1:

After you saved the data you can do this in the DonorsController:

$this->redirect(array(
   'controller' => 'donations',
   'action' => 'add',
   $this->Donor->getLastInsertId()
));

There is no need to return a redirect, it's useless because you get redirected. Notice that we pass the last inserted record id as get param in the redirect. The redirect method of the controller calls by default _stop() which calls exit().

CakePHP3: There is a discussion about changing that default behavior in 3.0. Looks like in CakePHP 3.0 the redirect() won't exit() by default any more.

DonationsController:

public function add($donorId = null) {
   // Get the donor to display it if you like to
   if ($this->request->is('post')) {
    $this->request->data['Donation']['donor_id'] = $donorId;
    // Save code here
   } 
}

I would not use the session here, specially not by saving it to a totally meaningless and generic value named "id". If at all I would use always meaningful names and namespaces, for example Donor.lastInsertId as session key.

It's not always clear where to put things if they're related but the rule of thumb goes that things should go into the domain they belong to, which is pretty clear in this case IMHO.

Edit: Leaving this edit here just if someone else needs it - it does not comply with the usage scenario of the asker. If you have the user logged in at this stage, modify the add function to check if the userId passed is the same as the one logged in:

DonationsController:

public function add($donorId = null) {
   // Get the donor to display it if you like to
   if ($this->request->is('post')) {
       if ($this->Auth->user('id') != $donorId) {
           throw new InvalidArgumentException();
       }
    $this->request->data['Donation']['donor_id'] = $donorId;
    // Save code here
   } 
}


回答2:

You can use also the same controller using more models with uses. Or you can also to ask to another controller with Ajax and morover to get response with Json.