一个Symfony2新手问题。
说我有1:M帖子:评论情况。
在单个帖子的“显示”视图中,我希望有一个新表单来创建评论,显然是对所显示帖子的评论。
默认情况下做的事情,我得到一个带有select的新表单,其中的选项都是Post(注意:显示的Post确实是选中的选项),这是好的但不太好。
我无法使用隐藏字段定义新表单,其隐藏字段的值以某种方式显示的帖子或其ID。
Symfony2是否需要使用数据转换器即使是这样的基本任务? 欢迎帮助。
答案 0 :(得分:0)
您可以创建一条评论路线,其父母帖子的ID为url参数,如下所示:
POST: http://localhost/post/123/comment (creates a comment for post 123)
您的routing.yml
可能如下所示:
acme_post_create_comment:
path: /post/{post_id}/comment
requirements: { post_id: "\d+" }
methods: "POST"
defaults: { _controller: ... }
根据您创建表单的方式,您必须指定此路线和父帖作为表单的操作(有关详细信息,请参阅表单上的Symfony文档)。
您的控制器可能如下所示:
class PostController extends Controller
{
...
public function createCommentAction(Request $request, $post_id)
{
$em = $this->getDoctrine()->getManager();
$post = $em->getrepository('AcmeBlogBundle:Post')->find($post_id);
if (!$post) {
throw $this->createNotFoundException('post not found');
}
$comment = new Comment();
$comment->setPost($post);
$form = $this->createForm(new CommentForm(), $comment);
$form->handleRequest($request);
if ($form->isValid()) {
// Persist comment and redirect to post
}
// Display comment form with errors
}
答案 1 :(得分:0)
以下与Data Transformer的工作方式相比,它非常简单。 它几乎与文档示例http://symfony.com/doc/current/cookbook/form/data_transformers.html
相同<?php
/* src/Mario/Bundle/BlogBundleForm/DataTransformer/PostToIdTransformer.php */
namespace Mario\Bundle\BlogBundle\Form;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Doctrine\Common\Persistence\ObjectManager;
use Mario\Bundle\BlogBundle\Entity\Issue;
class PostToIdTransformer implements DataTransformerInterface
{
/**
* @var ObjectManager
*/
private $om;
/**
* @param ObjectManager $om
*/
public function __construct(ObjectManager $om)
{
$this->om = $om;
}
/**
* Transforms an object (post) to a string (id).
*
* @param Post|null $post
* @return string
*/
public function transform($post)
{
if (null === $post) {
return "";
}
return $post->getId();
}
/**
* Transforms a string (id) to an object (post).
*
* @param string $id
*
* @return Post|null
*
* @throws TransformationFailedException if object (post) is not found.
*/
public function reverseTransform($id)
{
if (!$id) {
return null;
}
$post = $this->om
->getRepository('MarioBlogBundle:Post')
->findOneBy(array('id' => $id))
;
if (null === $post) {
throw new TransformationFailedException(sprintf(
'An post with id "%s" does not exist!',
$id
));
}
return $post;
}
}
?>
然后在我的CommentType中,我定义
public function buildForm(FormBuilderInterface $builder, array $options)
{
$entityManager = $options['em'];
$transformer = new PostToIdTransformer($entityManager);
$builder
->add('author')
->add('email')
->add('comment')
->add(
$builder->create('post', 'hidden')
->addModelTransformer($transformer));
}
我还需要在createForm
的CommentController定义中传递$ em/**
* Creates a form to create a Comment entity.
*
* @param Comment $entity The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createCreateForm(Comment $entity)
{
$form = $this->createForm(new CommentType(), $entity, array(
'action' => $this->generateUrl('Mario_Comment_create'),
'method' => 'POST',
'em' => $this->getDoctrine()->getEntityManager()
));
$form->add('submit', 'submit', array('label' => 'Scrivi commento'));
return $form;
}
所以,很容易。谢谢干杯
(评论:我想说,对于M:1关系,默认情况下,Symfony2应该为子obj创建一个新形式,其中(隐藏)值仅用于(唯一的)父obj.Symfony2确实知道该值。)