We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Form data not saved as model entity

Hi guys!

I try to to save the form, but I did not get. Like all of the documentation do, but it seems that somewhere pierced ...

    public function settingsAction() {

        $errors = false;

        $settings = Settings::find();

        $form = new SettingsForm($settings);

        if($this->request->isPost()) {

            $form->bind($_POST, $settings);

            foreach ($settings as $item) {
                if(!$item->save($_POST))
                    $errors = true;
            }

            //$settings->save();

            if ($errors)
                $this->flash->error('Error update.');
            else 
                $this->flash->success('Success update.');

        } else {
            $this->view->settings = $form;
        }
    }

and settings.volt:

{% for setting in settings.getElements() %}

                    <div class="form-group">
                        {{ setting.getLabel({'class': 'col-md-2 control-label'}) }}
                        <div class="col-lg-10">
                            {{ setting.render({'class':'form-control'}) }}
                        </div>
                    </div>

                {% endfor %}

database:

return error "Resultsets\Simple not found method save()"...

what am I doing wrong?

I think you're trying to apply the save mechanism on columns (or multiple rows). A Form class should represent a single row in the database (or additional relations with keys), so if you have multiple key->value pairs it won't work with a single form object.

You should create as many form classes as you have rows, and then iterate those in your save action, something like this:

public function settingsAction() {

        $errors = false;

        $settings = Settings::find();

        $forms[];
        foreach($settings as $row) {
            $forms[] = new SettingsForm($settings); // This probably wont work because the html inputs will have the same names
        }

        if($this->request->isPost()) {

            foreach($this->request->getPost() as $row) {
                // Same problem here, somehow you'll have to name the individual rows so you can reference them
                $form->bind($row, $settings);
                if($form->isValid() {
                    $settings->save();
                    $this->flash->success('Success update.');
                } else {
                    foreach ($form->getMessages() as $message) {
                        echo $message, '<br>'; // whatever
                        $this->flash->error('Error update.');
                    }
                }
            }

        } else {
            $this->view->settings = $form;
        }
    }

You'll have to name your inputs so each form field has a unique name... But I hope you get the idea ;]

Call to a member function getElements() on a non-object in

but thanks for a try. ^)

You'll have to change a few things ofc... Your volt template would have to be edited too :P Posting your Form class would also help!

But the basic problem is that you're using a single form for multiple rows

edited Oct '15

But the basic problem is that you're using a single form for multiple rows

Yes, I would like to make dynamic\ settings for my site...

thanks.



19.7k
Accepted
answer

hohoho! :) I come up a solution

    public function settingsAction() {

        $errors = false;

        if($this->request->isPost()) {

            foreach ($this->request->getPost() as $name => $value) {

                $settingsElement = Settings::findFirst("name = '$name'");
                $settingsElement->value = $value;

                if(!$settingsElement->save())
                    $errors = $settingsElement->getMessages();
            }

            if ($errors)
                $this->flash->error(implode('<br>', $errors));
            else 
                $this->flash->success('Success update.');

        } 

        $this->view->settings = new SettingsForm(Settings::find());
    }