在symfony中结合2种形式 [英] Combining 2 forms in symfony

查看:113
本文介绍了在symfony中结合2种形式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一本实体书,其中包含:

  / ** 
* @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

 #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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆