SpringBootでWebサイトを作る

2022年度システム開発実習

SpringBoot

本棚を移動しようとするとエラーになる問題を解消する

投稿日:

本を別の本棚に移動しようとするとエラーになってしまう。

これは、今の状態では1冊の本を複数の本棚に入れようとしている。
現実的に不可能なことをやろうとしているのでエラーになる。

本棚を移動するためには、元の本棚から本を取り出した後で、別の本棚に移動するという操作が必要になる。

package jp.bookshelf;

import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class BookController {
	@Autowired
	private BookRepository repository;
	@Autowired
	private BookshelfRepository bookshelfRepository;

	@RequestMapping(value = "/book", method = RequestMethod.GET)
	public ModelAndView list(ModelAndView mav) {
		mav.addObject("book", new Book());
		mav.setViewName("books");
		List<Book> list = repository.findAll();
		List<Bookshelf> bookshelfs = bookshelfRepository.findAll();
		mav.addObject("list", list);
		mav.addObject("bookshelfs", bookshelfs);
		return mav;
	}

	@RequestMapping(value = "/book", method = RequestMethod.POST)
	public ModelAndView post(ModelAndView mav,
			@ModelAttribute("book") Book book) {
		repository.saveAndFlush(book);
		return new ModelAndView("redirect:/book");
	}

	@RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
	public ModelAndView edit(ModelAndView mav,
			@PathVariable long id) {
		mav.setViewName("edit");
		Optional<Book> data = repository.findById(id);
		mav.addObject("book", data.get());
		return mav;
	}

	@RequestMapping(value = "/edit", method = RequestMethod.POST)
	public ModelAndView update(ModelAndView mav,
			@ModelAttribute("book") Book book) {
		repository.saveAndFlush(book);
		return new ModelAndView("redirect:/book");
	}

	@RequestMapping(value = "/push", method = RequestMethod.POST)
	public ModelAndView push(ModelAndView mav,
			@RequestParam("id") long id,
			@RequestParam("bookshelf") long bookshelfId) {
		Optional<Book> data = repository.findById(id);
		Book book = data.get();
		Bookshelf prev = book.getBookshelf();
		if (prev != null) {
			prev.removeBook(book);
			bookshelfRepository.saveAndFlush(prev);
		}
		if (bookshelfId != 0) {
			Optional<Bookshelf> bs = bookshelfRepository.findById(bookshelfId);
			Bookshelf bookshelf = bs.get();
			bookshelf.addBook(book);
			book.setBookshelf(bookshelf);
			bookshelfRepository.saveAndFlush(bookshelf);
			repository.saveAndFlush(book);
		} else {
			book.setBookshelf(null);
			repository.saveAndFlush(book);
			return new ModelAndView("redirect:/");
		}
		return new ModelAndView("redirect:/bookshelf/" + bookshelfId);
	}
}

本を本棚に入れた後で、本棚から取り出して、どの本棚にも入れないという操作もできるようにする。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>本のリスト</title>
<style type="text/css">
img.book-image {
	width: 100px;
}
</style>
</head>
<body>

<h2>本を追加</h2>
<form action="/book" method="post" th:object="${book}">
	タイトル: <input type="text" name="title" th:value="*{title}" />
	<br />
	著者: <input type="text" name="author" th:value="*{author}" />
	<br />
	画像URL: <input type="text" name="image" th:value="*{image}" />
	<br />
	<input type="submit" value="本を追加" />
</form>

<h1>本のリスト</h1>
<table>
	<tr>
		<th>画像</th><th>タイトル</th><th>著者名</th><th>操作</th><th>本棚</th>
	</tr>
	<tr th:each="book : ${list}">
		<td><img class="book-image" th:src="${book.image}" /></td>
		<td th:text="${book.title}"></td>
		<td th:text="${book.author}"></td>
		<td>
			<a th:href="@{'/edit/' + ${book.id}}">修正</a>
			<a th:href="@{'/delete/' + ${book.id}}">削除</a>
		</td>
		<td>
			今の本棚: <span th:if="${book.bookshelf != null}" th:text="${book.bookshelf.name}"></span>
			<form action="/push" method="post">
				<input type="hidden" name="id" th:value="${book.id}" />
				<select name="bookshelf">
				<option value="0">本棚に入れない</option>
				<th:block th:each="bookshelf : ${bookshelfs}">
				<option th:value="${bookshelf.id}" th:text="${bookshelf.name}"></option>
				</th:block>
			</select>に<button>移動</button>する
			<p th:if="${book.bookshelf != null}" th:text="${book.bookshelf.name}">
			</form>
		</td>
	</tr>
</table>

<a href="/">戻る</a>

</body>
</html>

BookshelfにremoveBook()を追加する。

	public void addBook(Book book) {
		books.add(book);
	}

	public void removeBook(Book book) {
		books.remove(book);
	}
}

-SpringBoot
-

Copyright© 2022年度システム開発実習 , 2025 All Rights Reserved Powered by STINGER.