One form and two models

How use one form with two models?



60.8k
public function formSubmitAction(){

    $rec1 = new \MyModels\Model1($_POST);

    $rec2 = new \MyModels\Model2($_POST);
}

?

Do NOT use the $_POST global as @Izopi4a has suggested, you should always use sanitisation when dealing with database data to mitigate chances of SQL injection etc.

Use Phalcon's Request class to get posted data and apply filters to the input:

$this->request->getPost()
edited Mar '16

An example where I have a blog post table, a user table, a tags table, but they are all within a single form. Note that this is just how I did it, it is just one way to do it.

// Within Controller method

    $post = Posts::findFirst($id);
    $tags = $this->getTagsForPost($id); // A private method to get tags from my tag map

    $form = new EditPostForm($post);

    if ($this->request->isPost()) {
        $this->savePost($form, $post); // see below
        $assocTags = $this->saveTags(); // nothing special either, process/save data from $this->request->getPost('tags')
        $this->saveTagMap($assocTags, $post->id); // saves associations to a tag map table
    }

    $this->view->setVars([
        'form' => $form,
        'tags' => $tags
    ]);

In my view on the edit page, I didn't need to merge this value into the form at all, just populate the value here.

<?php echo $form->render('tags', ['value' => $tags]);?>

Here is the save post method that was called in the controller, w/basic error handling.

    /**
     * Saves to post table
     */
    private function savePost(&$form, &$posts)
    {
        if (!$form->isValid($this->request->getPost())) {
            $this->flashSession->error($form->renderMessagesAsList());
        }

        $form->bind($this->request->getPost(), $posts);
        $post = $form->getEntity();

        if ($posts->save() == false) {
            $this->flashSession->error($posts->errorMessages());
            return false;
        }

        $this->flashSession->success($posts->savedIcon('Post saved.'));
        return true;
    }

I had some relationship setup in my Post model, so that Phalcon will do all the work, but some of the more complicated ideas like tags table and tagmap table I decided to do outside of the form as hinted in controller above.

// Within Models\Post
public function initialize()
{
    $this->belongsTo("author", "Models\\Users", "id", ['alias' => 'User']);
    $this->hasMany("id", "Models\\TagMap", "postId", ['alias' => 'TagMap']);
}

With that relationship, within the Form

class EditPostForm extends Form
{
    /**
     * Forms initializer
     *
     * @param Posts $user
     * @param array $options [null, 'edit', 'add']
     */
    public function initialize(Posts $post, $options)
    {
     ...

I could get the author like this

    // user is Models\Users from the established relationship in Models\Post above
    $post->user->getId();

Hope this gives you an idea, and hope it isn't too bad an example.