I am creating a library management system in Symfony to progress.
So I have a book, user, category entity.
So I want to create the borrow a book function. However, when I perform the action, the book does not change in the database (book must become borrowed).
So here is my controller (knowing that it is a user who borrows, and the user can addBook as there is a join):
<?php
namespace App\Controller;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use App\Entity\Book;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
class BookController extends AbstractController
{
//Home page of Book, to render all the books
#[Route('/book', name: 'app_book')]
public function index(ManagerRegistry $doctrine): Response
{
$books = $doctrine->getRepository(Book::class)->findAll();
return $this->render('book/index.html.twig', [
'controller_name' => 'BookController',
'books' => $books,
]);
}
// Show a book
#[Route("/book/{id}", name: 'book_show')]
public function show(Book $article, EntityManagerInterface $manager , Request $request, $id){
$repo = $manager->getRepository(Book::class);
$book = $repo->find($id);
return $this->render('book/show.html.twig', [
'book' => $book,
]);
}
// Display the borrow form
#[Route("/book/borrow/{id}", name: 'borrow_book')]
public function RenderBorrow(Book $book, EntityManagerInterface $manager, $id){
$repo = $manager->getRepository(Book::class);
$book = $repo->find($id);
return $this->render('book/borrow.html.twig', [
'book' => $book,
]);
}
// method to actually borrow the book, then redirect to the book page
#[Route("/book/borrowed/{id}", name: 'book_borrowed')]
public function borrow(Book $book, EntityManagerInterface $manager, $id){
$repo = $manager->getRepository(Book::class);
$book = $repo->find($id);
// return true or false if book is borrowed or not
$availabilty = $book->isBorrowed();
// if available, then the user can borrow it.
if($availabilty){
// we get the user.
/** @var \App\Entity\User $user */
$user = $this->getUser();
$user->addBook($book);
// the book borrow becomes borrowed.
$book->setBorrowed(true);
$manager->persist($book);
$manager->flush();
$manager->persist($user);
$manager->flush();
}
return $this->redirectToRoute('book_show', ['id' => $book->getId()]);
}
}
And my twig borrow.html.twig
{% extends 'base2.html.twig' %}
{% block title %} Emprunter {{ book.title}} {% endblock %}
{% block body %}
<!-- Page to borrow a specified book
-->
<!-- If book is borrowed, then we display yes, or else no. If no, we can display a
button to borrow it -->
<section >
<form action="{{ path('book_borrowed', {'id' : book.id })}}" method="post">
{% if not book.borrowed %}
<h5> Emprunter </h5>
<h6> Nom du livre : {{ book.title}}</h6>
<h6> Catégorie du livre : {{ book.categorie}}</h6>
<button type="submit" > Emprunter </button>
</form>
{% else %}
<div >
<button type="button" data-bs-dismiss="alert"></button>
<strong>Oh !</strong> <a href="#" >Vous tentez d'emprunter un livre déjà emprunté !
</div>
{% endif %}
</section>
{% endblock %}
Please help me, because normally afterwards the book should update and become borrowed...
CodePudding user response:
You are updating the borrowed boolean when availability is equal to true.
What you want to do is check if the book is not borrowed, and if it's not update the value of your boolean.
You do not need to persist $book
and $user
since they are already persisted. Also you only need to flush once at the end.
Moreover, Book $book
should give you the proper $book
depending on the id, without having to look it up yourself in the repository
You could replace your method with:
// method to actually borrow the book, then redirect to the book page
#[Route("/book/borrowed/{id}", name: 'book_borrowed')]
public function borrow(Book $book, EntityManagerInterface $manager, $id){
// if available, then the user can borrow it.
if(!$book->isBorrowed()){
// we get the user.
/** @var \App\Entity\User $user */
$user = $this->getUser();
$user->addBook($book);
// the book borrow becomes borrowed.
$book->setBorrowed(true);
$manager->flush();
}
return $this->redirectToRoute('book_show', ['id' => $book->getId()]);
}