Solved thread

This post is marked as solved. If you think the information contained on this thread must be part of the official documentation, please contribute submitting a pull request to its repository.

Model uniqueness validation triggered after successful insert

I have a problem, my model uniquenss validation is triggered after a succesfull update so I get both the success flash message and error flash message. I use slightly modified code from vokuro and invo examples.

//MODEL

public function validation()
{
    $validator = new Validation();

    $validator->add('email', new Uniqueness([
        "message" => "The email is already registered"
    ]));

    $validator->add("username", new Uniqueness([
        "message" => "The username is taken, try a new one"
    ]));

    return $this->validate($validator);
}

/**
 * Initialize method for model.
 */
public function initialize()
{
    $this->setSource("users");
    $this->belongsTo('role_id', 'Models\Role', 'id', ['alias' => 'Role']);
}

//CONTROLLER    

/**
 * @Route("/register", methods={"GET", "POST"})
 */
public function registerAction()
{
    $form = new RegisterForm();

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

        if ($form->isValid($this->request->getPost()) != false) {

            $user = new User([
                'name' => $this->request->getPost('name', 'striptags'),
                'email' => $this->request->getPost('email'),
                'password' => $this->security->hash($this->request->getPost('password')),
                'hash' => $this->security->getRandomBytes(),
                'role_id' => 5
            ]);

            $this->flash->setAutomaticHtml(true);

            if ($user->save()) {

                $this->flash->success('You have successfully registered');

                return $this->dispatcher->forward([
                    'controller' => 'auth',
                    'action' => 'register'
                ]);

            }

            $this->flash->error($user->getMessages());
        }
    }

    $this->view->form = $form;
}

//VIEW
    {{ form("class": "form-search") }}

  <div class="page-header">
      <h2>
          Sign Up
      </h2>
      </div>

    {{ content() }}
    {{ form.messages() }}

    <label>{{ form.label("name") }}</label>
    <div class="form-group {{ form.hasMessagesFor('name') ? 'has-error' : '' }}">
        {{ form.render("name") }}
    </div>

    <label>{{ form.label("username") }}</label>
    <div class="form-group {{ form.hasMessagesFor('username') ? 'has-error' : '' }}">
    <div class="input-group">
        <span class="input-group-addon"><i class="fa fa-user"></i></span>
        {{ form.render("username") }}
    </div>
    </div>

  <label>{{ form.label("email") }}</label>
  <div class="form-group {{ form.hasMessagesFor('email') ? 'has-error' : '' }}">
      <div class="input-group">
          <span class="input-group-addon">@</span>
          {{ form.render("email") }}
      </div>
  </div>

  <label>{{ form.label("password") }}</label>
  <div class="form-group {{ form.hasMessagesFor('password') ? 'has-error' : '' }}">
      {{ form.render("password") }}
  </div>

  <label>{{ form.label("confirmPassword") }}</label>
  <div class="form-group {{ form.hasMessagesFor('confirmPassword') ? 'has-error' : '' }}">
      {{ form.render("confirmPassword") }}
  </div>

  <label>
      {{ form.render("terms") }} {{ form.label("terms") }}
  </label>

  <div class="form-group">
      {{ form.render("Sign Up") }}
  </div>

  {{ form.render("csrf", ["value": security.getToken()]) }}
  {{ form.messageFor("csrf") }}

  <hr>

  {{ endForm() }}


174
Accepted
answer

Figured it out, when you use the same controller action for both the POST and GET http requests and if you dispatcher->forward to the same controller action after successfull entry the dispatcher will trigger both methods somehow, and thus the model will try to create the same user with the same data again