我正在运行带有Doctrine和这三个(相关)实体的Symfony 2.3:发布,作者和 AuthorPublication 。 作者和发布都与 AuthorPublication 有多对一的关系(因此它基本上是<...之间的多对多关系) strong>作者和发布但我需要 AuthorPublication 实体来订购出版物的作者)
我希望有一个表单,用户可以在其中创建新的出版物,并根据需要为该出版物选择尽可能多的作者。
我研究了这篇文章:How to Embed a Collection of Forms但我不明白如何将其应用于我的问题,因为 AuthorPublication 实体介于两者之间。
相关守则:
公开
<?php
namespace ind\PubBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="ind\PubBundle\Repository\PublicationRepository")
* @ORM\Table("publications")
*/
class Publication {
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $pid;
/**
* @ORM\OneToMany(targetEntity="AuthorPublication", mappedBy="publication")
* @ORM\OrderBy({"order_id" = "ASC"})
*/
protected $publicationAuthors;
//some more attributes + getters/seters
?>
作者
<?php
namespace ind\PubBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table("aid_author")
*/
class Author {
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $aid;
/**
* @ORM\Column(type="string", length=255)
*/
protected $author_surname;
/**
* @ORM\Column(type="string", length=255)
*/
protected $author_forename;
/**
* @ORM\OneToMany(targetEntity="AuthorPublication", mappedBy="author")
*/
protected $authorPublication;
?>
AuthorPublication
<?php
namespace ind\PubBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table("aid_pid")
*/
class AuthorPublication {
/**
* @ORM\Id
* @ORM\Column(type="integer")
*/
protected $aid;
/**
* @ORM\Id
* @ORM\Column(type="integer")
*/
protected $pid;
/**
* @ORM\Column(type="integer")
*/
protected $order_id;
/**
* @ORM\ManyToOne(targetEntity="Publication", inversedBy="publicationAuthors")
* @ORM\JoinColumn(name="pid", referencedColumnName="pid")
*/
protected $publication;
/**
* @ORM\ManyToOne(targetEntity="Author", inversedBy="authorPublication")
* @ORM\JoinColumn(name="aid", referencedColumnName="aid")
*/
protected $author;
?>
答案 0 :(得分:3)
您必须制作AuthorPublicationType表单。您将字段作者设为'entity',将其他字段设为...
您制作出版物类型包括AuthorPublication(Embedded Forms)。
然后您可以使用prototype和非常简单的javascript添加新的AuthorPublication。
请注意,当您必须首先使用authorPublication attribut保存您的实体出版物时。在更新发布之后,例如使用Publication和LifecycleCallbacks中的临时ArrayCollection定义authorPublication。
编辑:示例。
我的实体是Sport OneToMany SportParam ManyToOne ConfigParam。 SportParam由Sport,ConfigParam和值组成。
我想用多个ConfigParam创建一个新的Sport:
SportParamType:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('ConfigParam', 'entity', array(
'class' => 'PPHBSportScoringBundle:ConfigParam',
'property' => 'nom',
'multiple' => false,
'label'=>'Paramètre'
))
->add('valeur','number',array('precision'=>2))
;
}
SportType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('nom')
->add('SportParams', 'collection', array(
'type'=> new SportParamType(),
'allow_add' => true,
'allow_delete' => true,
'by_reference'=> false
))
;
}
我的form.html.twig:
{{ form_start(form) }}
{{ form_errors(form) }}
{{ form_row(form.nom) }}
<ul class=SportParams data-prototype="{{ form_widget(form.SportParams.vars.prototype)|e }}">
{% for param in form.SportParams %}
<li>
{{ form_errors(param.ConfigParam) }}
{{ form_widget(param.ConfigParam) }}
{{ form_errors(param.valeur) }}
{{ form_widget(param.valeur) }}
</li>
{% endfor %}
</ul>
<input type="submit" class="btn btn-primary" />
{{ form_end(form) }}
我的Javascript精炼,因为它包含更多代码(AJAX调用)。它可能包含一些错误。如果不清楚,请查看documentation:
<script type="text/javascript">
var $container = $('ul.SportParams');
// button to add a new SportParam
var $addSportParamLink = $('<a href="#" id="ajout_param" class="btn btn-primary btn-xs">Ajouter un paramètre</a>');
var $newLinkLi = $('<li></li>').append($addSportParamLink);
$(document).ready(function() {
//delete button on each existing SportParam
$container.find('li').each(function() {
addParamFormDeleteLink($(this));
});
//add button
$container.append($newLinkLi);
// adding a new form when cliking Add button
$addSportParamLink.on('click',function(e) {
e.preventDefault(); // évite qu'un #apparaisse dans l'URL
var index = $container.children().length-1;
addParamForm($container,$newLinkLi);
var bAffiche;
return false;
});
// adding a new form SportParam
function addParamForm($container, $newLinkLi) {
var $prototype = $container.attr('data-prototype');
var newForm = $prototype.replace(/__name__/g, $container.children().length-1);
var $newFormLi = $('<li></li>').append(newForm);
$newLinkLi.before($newFormLi);
addParamFormDeleteLink($newFormLi);
}
function addParamFormDeleteLink($paramFormLi){
var $removeFormA = $('<a href="#" class="btn btn-danger btn-xs">Supprimer</a>');
$paramFormLi.append($removeFormA);
$removeFormA.on('click', function(e) {
e.preventDefault();
$paramFormLi.remove();
});
}
});
</script>
体育实体致电回复:
/**
* sport
*
* @ORM\Table()
* @ORM\Entity
* @ORM\HasLifecycleCallbacks
* @ORM\Entity(repositoryClass="SportRepository")
*/
class Sport
{
...Entity attribut...
/**
* @var ArrayCollection
*
* To save Sport without SportParams
*/
private $SportParamsTMP;
...getter and setter ...
/**
* @ORM\PrePersist
*/
public function saveSportParams()
{
$this->SportParamsTMP = $this->SportParams;
$this->SportParams = null;
}
/**
* @ORM\PostPersist
*/
public function restoreSportParams()
{
if ($this->SportParamsTMP == !null) {
$this->SportParams = $this->SportParamsTMP;
}
$this->SportParamsTMP = null;
}
}
最后控制器的功能是添加一个新的Sport:
public function addAction()
{
$sport = new Sport();
$form = $this->createForm(new SportType(), $sport);
$request = $this->getRequest();
if ($request->getMethod() == "POST") {
$form->bind($request);
if($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($sport);
//saving sport without parameter
$em->flush();
//updating sport with parameter
$em->flush();
return $this->redirect($this->generateUrl('pphb_sport_liste'));
}
}
return $this->render('PPHBSportScoringBundle:Championnat/Sport:add.html.twig', array(
'form' => $form->createView(),
));
}
我希望它有所帮助 不知道这是否是最好的方法,但它对我有用。如果要改进的地方请告诉我。