Для отображения для конкретной книги отзывов, вам нужно реализовать OneToMany
соотношения в Book
сущности (в качестве обратной стороны), и ManyToOne
отношения в Review
сущности (как владеющему стороны).
Я искал для полных примеров, и я не мог найти, так вот моя попытка:
1) Создание Book
и Review
сущности, без каких-либо отношений, а также создавать их в базе данных тоже. Вы получите сообщение об ошибке, если попытаетесь создать таблицы вместе с отношениями, если эти таблицы еще не присутствуют в базе данных.
2) Теперь вы можете создать отношения
# AppBundle\Entity\Book.php
use Doctrine\Common\Collections\ArrayCollection;
...
class Book
...
/**
* @ORM\OneToMany(targetEntity="Review", mappedBy="book")
*/
private $reviews;
public function __construct()
{
$this->reviews = new ArrayCollection();
}
//... getters and setters for extra fields you might have
/**
* @return ArrayCollection|Review[]
*/
public function getReviews()
{
return $this->reviews;
}
// Notice here you don't need the setReviews() setter!
# AppBundle/Entity/Review.php
use AppBundle\Entity\Book;
...
class Review
...
/**
* @ORM\ManyToOne(targetEntity="Book", inversedBy="reviews")
*/
private $book;
//... getters and setters for extra fields you might have
/**
* @return Review
*/
public function getBook()
{
return $this->book;
}
/**
* Notice here is passed the entire book object
* @param Book $book
* @return $this
*/
public function setBook(Book $book)
{
$this->book = $book;
return $this;
}
3) применять эти отношения путем создания миграции или с помощью doctrine:schema:update --force
команды.
4) Создание форм, на основе сущностей
-> BookType: php bin/console doctrine:generate:form AppBundle:Book
-> ReviewType: php bin/console doctrine:generate:form AppBundle:Review
, и вы должны использовать EntityType
для того, чтобы получить книгу, принадлежащую этому массиву обзоров.
# AppBundle/Form/ReviewType.php
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\EntityRepository;
...
class ReviewType extends AbstractType
...
->add('book', EntityType::class, [
'class' => 'AppBundle:Book',
'placeholder' => ' ',
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('b');
},
'choice_label' => function($book){
return $book->getId();// in the <select> options put the ids from Book entity
},
'multiple' => false, // a user can select only one option per submission
'expanded' => false // options will be presented in a <select> dropdown; set this to true, to present the data in checkboxes
])
5) Действие для создания и сохранения книги, в контроллере:
# AppBundle/Controller/DefaultController.php
use AppBundle\Entity\Book;
use AppBundle\Form\BookType;
...
/**
* @Route("/book", name="book")
*/
public function bookAction(Request $request)
{
$book = new Book();
$form = $this->createForm(BookType::class, $book, [
'action' => $this->generateUrl('book'),
'method' => 'POST'
]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($book);
$em->flush();
return $this->redirectToRoute('book');
}
return $this->render('default/book.html.twig', ['form'=>$form->createView()]);
}
6) Действие для создания и сохранения обзора в контроллере
# AppBundle/Controller/DefaultController.php
use AppBundle\Entity\Review;
use AppBundle\Form\ReviewType;
...
/**
* @Route("/review", name="review")
*/
public function reviewAction(Request $request)
{
$review = new Review();
$form = $this->createForm(ReviewType::class, $review, [
'action' => $this->generateUrl('review'),
'method' => 'POST'
]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($review);
$em->flush();
return $this->redirectToRoute('review');
}
return $this->render('default/review.html.twig', ['form'=>$form->createView()]);
}
7) Для отображения отзывов для определенной книги:
# AppBundle/Controller/DefaultController.php
/**
* @Route("/", name="homepage")
*/
public function indexAction()
{
$reviews = $this->getDoctrine()->getRepository('AppBundle:Review')->findAll();
if (!$reviews) {
throw $this->createNotFoundException('No review(s) found!');
}
return $this->render('default/index.html.twig',['reviews'=>$reviews]);
}
8) Вид, чтобы отобразить отзывы (для книги и обзора, просто распечатать формы, поэтому я не буду размещать код, как это тривиально)
# app/Resources/views/default/index.html.twig
{% extends 'base.html.twig' %}
{% block body %}
{% for review in reviews %}
{{ review.comment ~ '-' ~ review.book.name }}
{% endfor %}
{% endblock %}
ли вы пытались использовать EntityType в вашем ReviewType? –
@DanCostinel Я обновил вопрос, чтобы вы поняли, что происходит лучше. – KTOV
Я предполагаю, что строка «Reviews» отображается вашей '{{form_end (form)}}'. Посмотрите, правильно ли вы отобрали соответствующее поле. –