gpt4 book ai didi

php - SonataAdminBundle 和 OneToOne 的关系

转载 作者:行者123 更新时间:2023-12-05 05:45:18 34 4
gpt4 key购买 nike

我在 PageSuperGridContent 之间有一对一的关系:

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity
* @ORM\Table(name="page")
* @ORM\HasLifecycleCallbacks
*/
class Page
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;

//...

/**
* @ORM\OneToOne(targetEntity="AppBundle\Entity\SuperGridContent", mappedBy="page", cascade={"persist", "remove"})
*/
protected $super_grid;

//...
}
<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity
* @ORM\Table(name="super_grid_content")
* @ORM\HasLifecycleCallbacks
*/
class SuperGridContent
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\OneToOne(targetEntity="AppBundle\Entity\Page", inversedBy="super_grid")
*/
private $page;

//...
}

然后在我的页面管理类中:

<?php

namespace AppBundle\Admin;

use AppBundle\Entity\Page;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Form\Type\ModelType;

class PageAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('super_grid', ModelType::class, [
'label' => 'Super Grid',
'required' => false,
])
// ...
;
}

// ...
}

问题是,当我创建或编辑 Page 时,super_grid 字段是一个带有所有现有 SuperGridContent 作为选项的选择标记。即使他们已经有 Page 关系。如果我选择其中之一,当然会失败,因为这种关系应该是唯一的。

我是不是遗漏了什么或者 Sonata 是否有办法处理它?<​​/p>

我正在使用 SonataAdminBundle 3.4

最佳答案

如果我对你的问题理解正确,我认为你可以使用 Symfony 实体类型而不是 Sonata documentation 中所述的模型类型.

但我也认为,如果您反转 OneToOne 关系的所有权,您的生活会容易得多。在您的示例中,SuperGridContent 拥有该关系,因此当您想要更新 Pagesuper_grid 时,您可能会遇到违反约束的情况。如果您将 SuperGridContent 类中的 inversedBy 更改为 mappedBy 并将 mappedBy 更改为 inversedBy Page 类(+ 如果您重新生成表格并确保级联逻辑符合您的需要)您应该没问题。

如果我理解得很好,您希望任何新的 Page 都只有可用的 super_grid 作为选择,而任何现有的 Page 都有它的当前 super_grid + 所有可用的 super_grid 作为选择。

然后像下面这样的东西就可以完成这项工作(注意我使用的是 Symfony 4.4,可能与您的实现有轻微的语法差异):

namespace App\Admin;

use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Form\FormMapper;
//use Sonata\AdminBundle\Form\Type\ModelType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\EntityRepository;
use App\Entity\Page;
use App\Entity\SuperGridContent;


final class PageAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $form): void
{
$subject = $this->getSubject();

if($subject->getId()){
$form
->add('super_grid', EntityType::class, [
'class' => SuperGridContent::class,
'query_builder' => function (EntityRepository $er) use($subject) {
return $er->createQueryBuilder('s')
->leftjoin('s.page', 'p')
->where('p.super_grid is null')
->orWhere('p = :my_page')
->setParameter('my_page', $subject)
;
},
]);
}
else{
$form
->add('super_grid', EntityType::class, [
'class' => SuperGridContent::class,
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('s')
->leftjoin('s.page', 'p')
->where('p.super_grid is null')
;
},
]);
}
}
}

关于php - SonataAdminBundle 和 OneToOne 的关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71426403/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com