I like the classic CRUD separation so I will say that the best practice is something like this:
class Crud extends Controller
{
protected $successMessage = 'Action has been successful.';
public function newAction()
{
$this->view->form = new MyForm();
}
public function createAction()
{
$this->checkRequest();
try {
$this->processForm($this->request->getPost());
$this->view->disable();
$this->flash->success($this->successMessage);
$this->redirect(); // redirect to edit or index
} catch (Exception $e) {
$this->flash->error($e->getMessage());
}
$this->dispatcher->forward(array('action' => 'new'));
}
public function editAction($id)
{
$this->view->record = MyModel::findById($id);
$this->view->form = new MyForm($this->view->record);
}
public function updateAction($id)
{
$this->checkRequest();
try {
$record = MyModel::findById($id);
$this->processForm($this->request->getPost(), $record);
$this->view->disable();
$this->flash->success($this->successMessage);
$this->redirect(); // redirect to edit or index
} catch (Exception $e) {
$this->flash->error($e->getMessage());
}
$this->dispatcher->forward(array('action' => 'edit'));
}
protected function checkRequest()
{
if (!$this->request->isPost()) {
throw new MyPostRequiredException();
}
}
public function deleteAction($id)
{
$this->view->disable();
try {
$this->scaffolding->doDelete($id);
$this->flash->success($this->successMessage);
} catch (Exception $e) {
$this->flash->error($e->getMessage());
}
$this->redirect(); // redirect to index/list action or something
}
private function processForm($postData, $model = null)
{
// perform your binding, saving etc., throw exceptions in case of failure or if form is not valid
}
}
Ofcourse we have some code repetition here. some things can be done other way, but this is just simple example. Main advantage of flow like this is clear separation for each process. In newAction volt template you have form pointed to createAction and in edit volt template - pointed to update.
Cheers!