Я плохо знаком с чашами Грааля и пытающийся создать форму, которая позволяет пользователю изменять адрес электронной почты, связанный с его счетом на сайт, который я создаю.
Это просит пользователя для их текущего пароля, и также для нового адреса электронной почты они хотят использовать. Если пользователь вводит неправильный пароль или недопустимый адрес электронной почты затем, он должен отклонить их с соответствующим сообщением об ошибке.
Теперь почтовая проверка может быть сделана посредством ограничений в чашах Грааля, но изменение пароля должно соответствовать их текущему паролю. Я реализовал эту проверку как метод на классе обслуживания.
См. код ниже:
def saveEmail =
{
def client = ClientUser.get(session.clientUserID)
client.email = params.email
if(clientUserService.checkPassword(session.clientUserID , params.password) ==false)
{
flash.message = "Incorrect Password"
client.discard()
redirect(action:'changeEmail')
}
else if(!client.validate())
{
flash.message = "Invalid Email Address"
redirect(action:'changeEmail')
}
else
{
client.save();
session.clientUserID = null;
flash.message = "Your email address has been changed, please login again"
redirect(controller: 'clientLogin' , action:'index')
}
}
Теперь то, что я заметил, это было нечетно, было то, что, если бы я ввел недопустимое электронное письмо затем, оно не сохранило бы изменения (как ожидалось), НО если бы я ввел неправильный пароль и действующий адрес электронной почты затем, то оно сохранило бы изменения и даже записало бы их обратно в базу данных даже при том, что оно даст корректное сообщение об ошибке "неверного пароля".
Я был озадачен так точки останова набора в весь, если/еще, если/еще блоки и нашел, что это поражало первое если бы оператор как ожидалось и поражало другие, таким образом, это никогда не прибывало бы через вызов в сохранение () метод, еще это было сохранено так или иначе.
После небольшого исследования я приехал через документацию для отбрасывания () метод, который Вы видите используемый в коде выше. Таким образом, я добавил это, но все еще никакую пользу. Я даже пытался использовать отбрасывание, затем перезагружая объект клиента от DB снова, но все еще провал.
Это очень печально, и я был бы благодарен за любую справку, так как я думаю, что это не должно, конечно, быть сложным требованием!
Grails закрывает вашу сессию Hibernate в конце веб-запроса, что приводит к вымыванию измененного объекта. Объект связан с вашей сессией Hibernate, потому что вы получили его через Hibernate (get()
). Если вы хотите избежать сброса изменений, вам нужно использовать discard()
.
Это делается автоматически при неудачном валидаторе, поэтому вам не нужно делать это при неудачной валидации.
Однако вы можете упростить код, либо перенеся эту логику в пользовательский валидатор на одно из ваших полей ClientUser
, который автоматически отбрасывает объект при неудаче, либо используя объект команды Grails, который также может инкапсулировать логику проверки. Тогда вы просто проверяете наличие ошибок в командном объекте.