Php 原则中的外键(Symfony)。如何将新的子级绑定到已存在的父级?

Php 原则中的外键(Symfony)。如何将新的子级绑定到已存在的父级?,php,symfony,doctrine,symfony5,Php,Symfony,Doctrine,Symfony5,有一个地区和城市的数据库。区域和城市表之间的关系是一对多的。下面是我在数据库中添加新城市的代码。它给出了一个错误: 我在互联网上只找到了一个解决方案——不仅在城市上,而且在地区上使用“$entity\u manager->persist()”。但在这种情况下,条令复制了数据库中已经存在的区域 Symfony文档确实涵盖了添加新的子项和新的父项,这是我不需要的 在控制器中: /** * @Route("/admin/insert/city", name="city

有一个地区和城市的数据库。区域和城市表之间的关系是一对多的。下面是我在数据库中添加新城市的代码。它给出了一个错误:

我在互联网上只找到了一个解决方案——不仅在城市上,而且在地区上使用“$entity\u manager->persist()”。但在这种情况下,条令复制了数据库中已经存在的区域

Symfony文档确实涵盖了添加新的子项和新的父项,这是我不需要的

在控制器中:

/**
 * @Route("/admin/insert/city", name="city")
 */
public function city(Request $request)
{
    // get list of regions
    $regions_in_database = $this->getDoctrine()->getRepository(Region::class)->findAll();

    // add the regions into an array
    $regions = [];
    foreach ($regions_in_database as $region) {
        $regions[(string)$region->getName()] = clone $region;
    }

    // Create Form
    $city = new City();
    $insert_city = $this->createForm(InsertCityType::class, $city, [
        'regions_array' => $regions,
    ]);

    // Checking for the existence of regions
    if (!$regions_in_database) {
        $insert_city->addError(new FormError("Отсутствуют регионы!
            Пожалуйста, перейдите по ссылке /insert/region и добавьте соответствующий регион"));
    }

    // Отправка формы
    $insert_city->handleRequest($request);
    if ($insert_city->isSubmitted() && $insert_city->isValid()) {

        // Check if there is already such a city in the database
        $repository = $this->getDoctrine()->getRepository(City::class);
        $city_in_database = $repository->findOneBy(
            [
                'name' => $city->getName(),
                'region' => $city->getRegion(),
            ]
        );

        // If the city is in the database, throw an error
        if ($city_in_database) {
            $insert_city->addError(new FormError('Такой город уже существует!'));
        }
        else {
            $entity_manager = $this->getDoctrine()->getManager();
            $entity_manager->persist($city);
            $entity_manager->flush();

            $city = new City();
            $insert_city = $this->createForm(InsertCityType::class, $city, [
                'regions_array' => $regions,
            ]);
        }
    }

    return $this->render('admin/insert/city/city.html.twig', [
        'insert_city' => $insert_city->createView(),
    ]);
}
class InsertCityType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('region', ChoiceType::class, [
                'choices'  => $options['regions_array'],
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Cities::class,
            'regions_array' => null,
        ]);

        $resolver->setAllowedTypes('regions_array', 'array');
    }
}
/**
 * Regions
 *
 * @ORM\Table(name="regions")
 * @ORM\Entity
 */
class Regions
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255, nullable=false)
     */
    private $name;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }
}
/**
 * Cities
 *
 * @ORM\Table(name="cities", indexes={@ORM\Index(name="region", columns={"region"})})
 * @ORM\Entity
 */
class Cities
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255, nullable=false)
     */
    private $name;

    /**
     * @var \Regions
     *
     * @ORM\ManyToOne(targetEntity="Regions", inversedBy="cities")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="region", referencedColumnName="id")
     * })
     */
    private $region;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function getRegion(): ?Regions
    {
        return $this->region;
    }

    public function setRegion(?Regions $region): self
    {
        $this->region = $region;

        return $this;
    }
}
表单类:

/**
 * @Route("/admin/insert/city", name="city")
 */
public function city(Request $request)
{
    // get list of regions
    $regions_in_database = $this->getDoctrine()->getRepository(Region::class)->findAll();

    // add the regions into an array
    $regions = [];
    foreach ($regions_in_database as $region) {
        $regions[(string)$region->getName()] = clone $region;
    }

    // Create Form
    $city = new City();
    $insert_city = $this->createForm(InsertCityType::class, $city, [
        'regions_array' => $regions,
    ]);

    // Checking for the existence of regions
    if (!$regions_in_database) {
        $insert_city->addError(new FormError("Отсутствуют регионы!
            Пожалуйста, перейдите по ссылке /insert/region и добавьте соответствующий регион"));
    }

    // Отправка формы
    $insert_city->handleRequest($request);
    if ($insert_city->isSubmitted() && $insert_city->isValid()) {

        // Check if there is already such a city in the database
        $repository = $this->getDoctrine()->getRepository(City::class);
        $city_in_database = $repository->findOneBy(
            [
                'name' => $city->getName(),
                'region' => $city->getRegion(),
            ]
        );

        // If the city is in the database, throw an error
        if ($city_in_database) {
            $insert_city->addError(new FormError('Такой город уже существует!'));
        }
        else {
            $entity_manager = $this->getDoctrine()->getManager();
            $entity_manager->persist($city);
            $entity_manager->flush();

            $city = new City();
            $insert_city = $this->createForm(InsertCityType::class, $city, [
                'regions_array' => $regions,
            ]);
        }
    }

    return $this->render('admin/insert/city/city.html.twig', [
        'insert_city' => $insert_city->createView(),
    ]);
}
class InsertCityType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('region', ChoiceType::class, [
                'choices'  => $options['regions_array'],
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Cities::class,
            'regions_array' => null,
        ]);

        $resolver->setAllowedTypes('regions_array', 'array');
    }
}
/**
 * Regions
 *
 * @ORM\Table(name="regions")
 * @ORM\Entity
 */
class Regions
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255, nullable=false)
     */
    private $name;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }
}
/**
 * Cities
 *
 * @ORM\Table(name="cities", indexes={@ORM\Index(name="region", columns={"region"})})
 * @ORM\Entity
 */
class Cities
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255, nullable=false)
     */
    private $name;

    /**
     * @var \Regions
     *
     * @ORM\ManyToOne(targetEntity="Regions", inversedBy="cities")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="region", referencedColumnName="id")
     * })
     */
    private $region;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function getRegion(): ?Regions
    {
        return $this->region;
    }

    public function setRegion(?Regions $region): self
    {
        $this->region = $region;

        return $this;
    }
}
表格:

/**
 * @Route("/admin/insert/city", name="city")
 */
public function city(Request $request)
{
    // get list of regions
    $regions_in_database = $this->getDoctrine()->getRepository(Region::class)->findAll();

    // add the regions into an array
    $regions = [];
    foreach ($regions_in_database as $region) {
        $regions[(string)$region->getName()] = clone $region;
    }

    // Create Form
    $city = new City();
    $insert_city = $this->createForm(InsertCityType::class, $city, [
        'regions_array' => $regions,
    ]);

    // Checking for the existence of regions
    if (!$regions_in_database) {
        $insert_city->addError(new FormError("Отсутствуют регионы!
            Пожалуйста, перейдите по ссылке /insert/region и добавьте соответствующий регион"));
    }

    // Отправка формы
    $insert_city->handleRequest($request);
    if ($insert_city->isSubmitted() && $insert_city->isValid()) {

        // Check if there is already such a city in the database
        $repository = $this->getDoctrine()->getRepository(City::class);
        $city_in_database = $repository->findOneBy(
            [
                'name' => $city->getName(),
                'region' => $city->getRegion(),
            ]
        );

        // If the city is in the database, throw an error
        if ($city_in_database) {
            $insert_city->addError(new FormError('Такой город уже существует!'));
        }
        else {
            $entity_manager = $this->getDoctrine()->getManager();
            $entity_manager->persist($city);
            $entity_manager->flush();

            $city = new City();
            $insert_city = $this->createForm(InsertCityType::class, $city, [
                'regions_array' => $regions,
            ]);
        }
    }

    return $this->render('admin/insert/city/city.html.twig', [
        'insert_city' => $insert_city->createView(),
    ]);
}
class InsertCityType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('region', ChoiceType::class, [
                'choices'  => $options['regions_array'],
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Cities::class,
            'regions_array' => null,
        ]);

        $resolver->setAllowedTypes('regions_array', 'array');
    }
}
/**
 * Regions
 *
 * @ORM\Table(name="regions")
 * @ORM\Entity
 */
class Regions
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255, nullable=false)
     */
    private $name;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }
}
/**
 * Cities
 *
 * @ORM\Table(name="cities", indexes={@ORM\Index(name="region", columns={"region"})})
 * @ORM\Entity
 */
class Cities
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255, nullable=false)
     */
    private $name;

    /**
     * @var \Regions
     *
     * @ORM\ManyToOne(targetEntity="Regions", inversedBy="cities")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="region", referencedColumnName="id")
     * })
     */
    private $region;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function getRegion(): ?Regions
    {
        return $this->region;
    }

    public function setRegion(?Regions $region): self
    {
        $this->region = $region;

        return $this;
    }
}

地区类别:

/**
 * @Route("/admin/insert/city", name="city")
 */
public function city(Request $request)
{
    // get list of regions
    $regions_in_database = $this->getDoctrine()->getRepository(Region::class)->findAll();

    // add the regions into an array
    $regions = [];
    foreach ($regions_in_database as $region) {
        $regions[(string)$region->getName()] = clone $region;
    }

    // Create Form
    $city = new City();
    $insert_city = $this->createForm(InsertCityType::class, $city, [
        'regions_array' => $regions,
    ]);

    // Checking for the existence of regions
    if (!$regions_in_database) {
        $insert_city->addError(new FormError("Отсутствуют регионы!
            Пожалуйста, перейдите по ссылке /insert/region и добавьте соответствующий регион"));
    }

    // Отправка формы
    $insert_city->handleRequest($request);
    if ($insert_city->isSubmitted() && $insert_city->isValid()) {

        // Check if there is already such a city in the database
        $repository = $this->getDoctrine()->getRepository(City::class);
        $city_in_database = $repository->findOneBy(
            [
                'name' => $city->getName(),
                'region' => $city->getRegion(),
            ]
        );

        // If the city is in the database, throw an error
        if ($city_in_database) {
            $insert_city->addError(new FormError('Такой город уже существует!'));
        }
        else {
            $entity_manager = $this->getDoctrine()->getManager();
            $entity_manager->persist($city);
            $entity_manager->flush();

            $city = new City();
            $insert_city = $this->createForm(InsertCityType::class, $city, [
                'regions_array' => $regions,
            ]);
        }
    }

    return $this->render('admin/insert/city/city.html.twig', [
        'insert_city' => $insert_city->createView(),
    ]);
}
class InsertCityType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('region', ChoiceType::class, [
                'choices'  => $options['regions_array'],
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Cities::class,
            'regions_array' => null,
        ]);

        $resolver->setAllowedTypes('regions_array', 'array');
    }
}
/**
 * Regions
 *
 * @ORM\Table(name="regions")
 * @ORM\Entity
 */
class Regions
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255, nullable=false)
     */
    private $name;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }
}
/**
 * Cities
 *
 * @ORM\Table(name="cities", indexes={@ORM\Index(name="region", columns={"region"})})
 * @ORM\Entity
 */
class Cities
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255, nullable=false)
     */
    private $name;

    /**
     * @var \Regions
     *
     * @ORM\ManyToOne(targetEntity="Regions", inversedBy="cities")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="region", referencedColumnName="id")
     * })
     */
    private $region;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function getRegion(): ?Regions
    {
        return $this->region;
    }

    public function setRegion(?Regions $region): self
    {
        $this->region = $region;

        return $this;
    }
}
城市级:

/**
 * @Route("/admin/insert/city", name="city")
 */
public function city(Request $request)
{
    // get list of regions
    $regions_in_database = $this->getDoctrine()->getRepository(Region::class)->findAll();

    // add the regions into an array
    $regions = [];
    foreach ($regions_in_database as $region) {
        $regions[(string)$region->getName()] = clone $region;
    }

    // Create Form
    $city = new City();
    $insert_city = $this->createForm(InsertCityType::class, $city, [
        'regions_array' => $regions,
    ]);

    // Checking for the existence of regions
    if (!$regions_in_database) {
        $insert_city->addError(new FormError("Отсутствуют регионы!
            Пожалуйста, перейдите по ссылке /insert/region и добавьте соответствующий регион"));
    }

    // Отправка формы
    $insert_city->handleRequest($request);
    if ($insert_city->isSubmitted() && $insert_city->isValid()) {

        // Check if there is already such a city in the database
        $repository = $this->getDoctrine()->getRepository(City::class);
        $city_in_database = $repository->findOneBy(
            [
                'name' => $city->getName(),
                'region' => $city->getRegion(),
            ]
        );

        // If the city is in the database, throw an error
        if ($city_in_database) {
            $insert_city->addError(new FormError('Такой город уже существует!'));
        }
        else {
            $entity_manager = $this->getDoctrine()->getManager();
            $entity_manager->persist($city);
            $entity_manager->flush();

            $city = new City();
            $insert_city = $this->createForm(InsertCityType::class, $city, [
                'regions_array' => $regions,
            ]);
        }
    }

    return $this->render('admin/insert/city/city.html.twig', [
        'insert_city' => $insert_city->createView(),
    ]);
}
class InsertCityType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('region', ChoiceType::class, [
                'choices'  => $options['regions_array'],
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Cities::class,
            'regions_array' => null,
        ]);

        $resolver->setAllowedTypes('regions_array', 'array');
    }
}
/**
 * Regions
 *
 * @ORM\Table(name="regions")
 * @ORM\Entity
 */
class Regions
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255, nullable=false)
     */
    private $name;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }
}
/**
 * Cities
 *
 * @ORM\Table(name="cities", indexes={@ORM\Index(name="region", columns={"region"})})
 * @ORM\Entity
 */
class Cities
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255, nullable=false)
     */
    private $name;

    /**
     * @var \Regions
     *
     * @ORM\ManyToOne(targetEntity="Regions", inversedBy="cities")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="region", referencedColumnName="id")
     * })
     */
    private $region;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function getRegion(): ?Regions
    {
        return $this->region;
    }

    public function setRegion(?Regions $region): self
    {
        $this->region = $region;

        return $this;
    }
}

按照以下步骤操作:创建一个新城市,获得正确的区域,然后将新城市添加到该区域,并将其保存到数据库中

为此,请添加您所在区域实体中的城市列表,如下所示:

/**
 * @var ArrayCollection
 *
 * @ORM\OneToMany(targetEntity="City", mappedBy="region", cascade={"persist"})
 */
private $cities; // This attribut will not appear in your database

public function __construct() {
    $this->cities = new ArrayCollection();
}
使用以下命令生成资产和getter
php-bin/console-make:entity--regenate

现在,您可以在区域中添加城市:

$theRegion = fetchMyRegion(); // Fetch the region that you want
$theRegion->addCity($myCity); // Don't forget 'cities' attribut is a ArrayCollection
$entity_manager->persist($theRegion); // City object saves automatically in your database
$entity_manager->flush(); // The new city is now created and linked to the region

按照以下步骤操作:创建一个新城市,获得正确的区域,然后将新城市添加到该区域,并将其保存到数据库中

为此,请添加您所在区域实体中的城市列表,如下所示:

/**
 * @var ArrayCollection
 *
 * @ORM\OneToMany(targetEntity="City", mappedBy="region", cascade={"persist"})
 */
private $cities; // This attribut will not appear in your database

public function __construct() {
    $this->cities = new ArrayCollection();
}
使用以下命令生成资产和getter
php-bin/console-make:entity--regenate

现在,您可以在区域中添加城市:

$theRegion = fetchMyRegion(); // Fetch the region that you want
$theRegion->addCity($myCity); // Don't forget 'cities' attribut is a ArrayCollection
$entity_manager->persist($theRegion); // City object saves automatically in your database
$entity_manager->flush(); // The new city is now created and linked to the region