在symfony中结合2种形式 [英] Combining 2 forms in symfony
问题描述
我有一本实体书,其中包含:
/ **
* @var \Doctrine\ Common \Collections\\ArrayCollection
* @ ORM\OneToMany(targetEntity =Reviewr\\ReviewBundle\Entity\Review,mappedBy =bookID)
* /
保护$审查;
在Review实体中,我有字段来表示:
userID
bookID
过帐
过帐
在我的BookType中,我试图创建包含ReviewType窗体的表单:
<$ c
$ builder-> add('author')
- > add('title')$ b public function buildForm(FormBuilderInterface $ builder,array $ options) ('submit',SubmitType :: class); $ b - > add('summary')
- > add('reviews',ReviewType :: class)
- > add
}
然而,我似乎无法得到这个工作。即时通讯只是试图有一个表单,使用字段从书实体和审查实体之一。
我收到此错误:
表单的视图数据有望成为Reviewr \ReviewsBundle\Entity\Review类的一个实例,但它是类Doctrine\Common\Collections的一个实例\ArrayCollection。
有谁知道我做错了什么?
更新
使用当前的答案,它最终显示了一些内容..只是一个字符串评论,而不是ReviewType表单中的字段(userID,bookID,posted和comment)在下图中:
为什么不显示字段?
为了显示特定图书的评论,您需要实现
关系(作为反面),以及 Book
实体中的OneToMany ManyToOne
关系在审查
实体(作为拥有方)。
我搜索了完整的例子, t找到任何,所以这里是我的尝试:
$ b 1)创建 Book
和查看
个实体,而没有任何关系,并在数据库中创建它们。如果您尝试在关系中创建表格,并且数据库中尚未存在表格,那么您会得到一个错误。
2)现在您可以创建关系
#AppBundle \Entity\Book.php
使用Doctrine\Common\Collections\ ArrayCollection的;
...
class Book
...
/ **
* @ ORM\OneToMany(targetEntity =Review,mappedBy =book)
* /
私人$ reviews;
public function __construct()
{
$ this-> reviews = new ArrayCollection();
}
// ...额外字段的getters和setter可能有
/ **
* @return ArrayCollection | Review []
* /
public function getReviews()
{
return $ this-> reviews;
}
//注意这里你不需要setReviews()setter!
#AppBundle / Entity / Review.php
使用AppBundle \Entity\Book;
...
class Review
...
/ **
* @ ORM\ManyToOne(targetEntity =Book,inversedBy =reviews)
* /
private $ book;
// ...额外字段的getters和setter可能有
/ **
* @return回顾
* /
public function getBook()
{
return $ this-> book;
}
/ **
*注意这里传递的是整个图书对象
* @param Book $ book
* @return $ this
* /
public function setBook(Book $ book)
{
$ this-> book = $ book;
返回$ this;
3)通过创建迁移或通过使用 doctrine:schema:update --force
命令。
$ b 4)根据实体创建表单
- > BookType: php bin / console doctrine:generate:form AppBundle:Book
- > ReviewType: php bin / console doctrine:generate:form AppBundle:Review
,您需要使用 EntityType $ c
#AppBundle / Form / ReviewType.php
使用Symfony \ Bridge \Doctrine\Form\Type\EntityType;
使用Doctrine \ORM \EntityRepository;
...
class ReviewType extends AbstractType
...
- > add('book',EntityType :: class,[
'class'=> ;'AppBundle:Book',
'placeholder'=>'',
'query_builder'=> function(EntityRepository $ er){
return $ er-> createQueryBuilder('在< select>选项中放置$ b $);
},
'choice_label'=>函数($ book){
return $ book-> getId来自Book entity
},
'multiple'=> false的ID,//用户每次提交只能选择一个选项
'expanded'=> false //选项将会在< select>下拉列表中提供;将其设置为true,以在复选框中显示数据
])
5)在控制器中创建和保存图书的操作:
#AppBundle / Controller / DefaultController。 php
使用AppBundle \Entity\Book;
使用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()]);
$ / code>
6)在控制器中创建和保存评论的操作
#AppBundle / Controller / DefaultController.php
使用AppBundle \Entity \Review;
使用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') - > ;找到所有();
if(!$ reviews){
throw $ this-> createNotFoundException('No review s(s)found!');
}
return $ this-> render('default / index.html.twig',['reviews'=> $ reviews]);
code
8)显示评论的视图(对于书籍和评论,只是列印表格,所以我不会发布代码,这是微不足道的) #app / Resources / views / default / index .html.twig
{%extends'base.html.twig'%}
{%block body%}
{%用于评论中的评论%}
{{review.comment〜' - '〜review.book.name}}
{%endfor%}
{%endblock%}
I have an entity Book which contains:
/**
* @var \Doctrine\Common\Collections\ArrayCollection
* @ORM\OneToMany(targetEntity="Reviewr\ReviewsBundle\Entity\Review", mappedBy="bookID")
*/
protected $reviews;
Within the Review entity i have fields to represent:
userID
bookID
posted
comment
Within my BookType, I am trying to create the form which also includes the fields from the ReviewType form:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('author')
->add('title')
->add('summary')
->add('reviews', ReviewType::class)
->add('submit', SubmitType::class);
}
However, i can't seem to get this working. im just trying to have a form which uses fields from the book entity and review entity in one.
I recieve this error:
The form's view data is expected to be an instance of class Reviewr\ReviewsBundle\Entity\Review, but is an instance of class Doctrine\Common\Collections\ArrayCollection.
Does anyone know what im doing wrong?
UPDATE
With the current answer, it finally displays something.. just a string "Reviews" rather than the fields from the ReviewType form (userID, bookID, posted and comment) as shown in the image below:
Why is it not displaying the fields?
解决方案 In order to display reviews for a particular book, you need to implement a OneToMany
relation in Book
entity (as the inverse side), and a ManyToOne
relation in Review
entity (as the owning side).
I've searched for complete examples, and I couldn't find any, so here's my try:
1) Create the Book
and Review
entities, without any relationship, and create them in the database too. You'll get an error if you try to create the tables alongside the relationships, if the tables are not already being present in the database.
2) Now you can create the relationships
# 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) Apply these relations by creating the migrations or by using doctrine:schema:update --force
command.
4) Create the forms, based on the entities
-> BookType: php bin/console doctrine:generate:form AppBundle:Book
-> ReviewType: php bin/console doctrine:generate:form AppBundle:Review
, and you need to use the EntityType
in order to get the book belonging to that array of reviews.
# 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) Action for creating and saving a book, in the controller:
# 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) Action for creating and saving a review, in the controller
# 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) For displaying the reviews for a particular book:
# 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) The view to display the reviews (for book and review, just print the forms, so I won't post the code, as is trivial)
# app/Resources/views/default/index.html.twig
{% extends 'base.html.twig' %}
{% block body %}
{% for review in reviews %}
{{ review.comment ~ '-' ~ review.book.name }}
{% endfor %}
{% endblock %}
这篇关于在symfony中结合2种形式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!