Я работаю над веб-сайтом, на котором пользователи могут добавлять и редактировать объекты (описание, в частности, не имеет значения).
Я реализую его, используя Thymeleaf для внешнего интерфейса, Spring MVC для внутреннего интерфейса и JPA для логики базы данных. Сейчас я пытаюсь реализовать логику редактирования, но я не знаю, какой это лучший способ сделать это.
Я думаю: показать пользователю все поля ввода (на странице HTML), которые ему разрешено редактировать, уже заполненные текущими значениями. Затем он может редактировать любые поля и, наконец, нажать кнопку редактирования, чтобы сохранить изменения.
Получив новый объект в бэкэнде, я извлекаю старую версию из базы данных, чтобы проверить, какое поле изменил пользователь. Для каждого измененного поля я обновляю старую версию и только после завершения вызываю метод JPA save и сохраняю новую версию этого объекта.
Есть ли лучший способ сделать это?
Было бы идеально, если бы объект, который я поместил внутри модели, чтобы отобразить все его поля пользователю на HTML-странице, мог содержать всю информацию о старом объекте, а не только те, которые пользователь может изменить. Позвольте мне лучше объяснить, что я пытаюсь сказать на примере:
Скажем, объект, который мы пытаемся отредактировать, называется его Person и имеет следующие атрибуты:
- id
- имя
- Фамилия
- деньги
- ник
- секс
Но пользователь может редактировать только следующие атрибуты:
поэтому контроллер, обрабатывающий запрос get страницы, будет выглядеть так:
@GetMapping("person/{personId}/edit")
public String getEditPersonPage(@PathVariable Integer personId, Model model) {
Person person = personService.getById(personId); //person has all the attributes filled in
model.addAttribute("person", person);
и контроллер, который обрабатывает запрос put, выглядит следующим образом:
@PutMapping("person/{personId}/edit")
public String editPerson(@ModelAttribute Person person, @PathVariable Integer personId){
personService.editPerson(person); //person has only the three fields filled in and all the other attributes as NULL
return "redirect:/person/" + personId;
}
HTML-страница:
<form th:object="${person}" th:method="PUT">
<fieldset>
<p th:text="*{id}"></p>
<p th:text="*{name}"></p>
<p th:text="*{surname}"></p>
<input type="number" th:field="*{money}" th:value="*{money}" />
<input type="text" th:field="*{nickname}" th:value="*{nickname}" />
<input type="text" th:field="*{sex}" th:value="*{sex}" />
<input type="submit" value="Edit" />
</fieldset>
</form>
Когда я вставляю объект person внутри модели для рендеринга HTML-страницы, объект имеет все атрибуты. Действительно, я могу решить, какие из его атрибутов отображаются на странице HTML (в данном случае только три: деньги, псевдоним и пол). Но когда пользователь нажимает кнопку «Отправить» (редактировать), я получаю только поля, отображаемые внутри HTML-страницы (деньги, псевдоним, пол). Так что мне нужно сделать следующее: я должен взять эти три поля, проверить, не изменились ли они, и если да, обновить старую версию.
Было бы идеально, если бы пользователь нажал кнопку отправки, контроллер мог бы получить все поля человека (а не только те три, которые ему разрешено обновлять). В этом случае я мог бы пропустить этап проверки и сохранить новую версию непосредственно в базе данных (со старыми значениями без изменений и без значения NULL).
Есть мысли?