【问题标题】:Passing parent entity Id into child form将父实体 ID 传递给子表单
【发布时间】:2020-12-07 09:00:12
【问题描述】:

美好的一天, 我将实体 ScheduledCommand 与 OneToMany 关联到 ScheduledCommandLimitRange

/**
 * @ORM\MappedSuperclass (repositoryClass="Synolia\SyliusSchedulerCommandPlugin\Repository\ScheduledCommandRepository")
 * @ORM\Table("scheduled_command")
 */
class ScheduledCommand implements ScheduledCommandInterface
{
    /**
     * @var int|null
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @var string
     * @ORM\Column(type="string")
     */
    private $name = '';

    /**
     * @var string
     * @ORM\Column(type="string")
     */
    private $command = '';

    /**
     * @var int
     * @ORM\Column(type="integer")
     */
    private $priority = 0;

    /**
     * @ORM\OneToMany(targetEntity="ScheduledCommandLimitRange", mappedBy="scheduledCommand", orphanRemoval=true, cascade={"persist"})
     * @ORM\JoinColumn(nullable=false)
     */
    private $commandLimitRanges;

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

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

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

        return $this;
    }

    public function getCommand(): string
    {
        return $this->command;
    }

    public function setCommand(string $command): ScheduledCommandInterface
    {
        $this->command = $command;

        return $this;
    }

    public function getPriority(): int
    {
        return $this->priority;
    }

    public function setPriority(int $priority): ScheduledCommandInterface
    {
        $this->priority = $priority;

        return $this;
    }

    public function getCommandLimitRanges(): ?Collection
    {
        return $this->commandLimitRanges;
    }

    public function setCommandLimitRanges(Collection $commandLimitRange): ?Collection
    {
        $this->commandLimitRanges = $commandLimitRange;
        return $this->commandLimitRanges;
    }
}

这是我的 ManyToOne 课程:

/**
 * @ORM\Entity(repositoryClass="Synolia\SyliusSchedulerCommandPlugin\Repository\ScheduledCommandLimitRangeRepository")
 * @ORM\Table(name="scheduled_command_limit_range")
 */
class ScheduledCommandLimitRange implements ScheduledCommandLimitRangeInterface
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @var \DateTime|null
     * @ORM\Column(type="datetime", nullable=true)
     */
    private $timeFrom;

    /**
     * @var \DateTime|null
     * @ORM\Column(type="datetime", nullable=true)
     */
    private $timeTo;

    /**
     * @ORM\ManyToOne(targetEntity="ScheduledCommand", inversedBy="commandLimitRanges")
     */
    private $scheduledCommand;

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

    public function getTimeFrom(): ?\DateTime
    {
        return $this->timeFrom;
    }

    public function setTimeFrom(?\DateTime $timeFrom): ScheduledCommandLimitRangeInterface
    {
        $this->timeFrom = $timeFrom;

        return $this;
    }

    public function getTimeTo(): ?\DateTime
    {
        return $this->timeTo;
    }

    public function setTimeTo(?\DateTime $timeTo): ScheduledCommandLimitRangeInterface
    {
        $this->timeTo = $timeTo;

        return $this;
    }

    public function getScheduledCommand(): ?ScheduledCommand
    {
        return $this->scheduledCommand;
    }
    public function setScheduledCommand(ScheduledCommand $scheduledCommand): ?ScheduledCommand
    {
        $this->scheduledCommand = $scheduledCommand;

        return $this;
    }

我的 ScheduledCommandType 在一个字段中具有 CollectionType,其 entry_type 为 CommandLimitType。

final class ScheduledCommandType extends AbstractType
{
    /**
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('name')
            ->add('command', CommandChoiceType::class)
            ->add('arguments')
            ->add('cronExpression')
            ->add('commandLimitRanges', CollectionType::class, [
                'label' => 'sylius.ui.scheduled_command_limit',
                'entry_type' => CommandLimitType::class,
                'allow_add' => true,
                'allow_delete' => true,
                'by_reference' => false,
                'inherit_data' => true,
                'entry_options'  => array(
                        'scheduledCommand' => 'id'),
                ])
            ->add('logFile')
            ->add('priority')
            ->add('executeImmediately')
            ->add('enabled')
        ;
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => ScheduledCommand::class,
        ]);
    }
} 

这是我的条目类型:

class CommandLimitType extends AbstractType
{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $builder
            ->add('timeTo', DateTimeType::class, [
                'widget' => 'single_text',

            ])
            ->add('timeFrom', DateTimeType::class, [
                'widget' => 'single_text'
            ])
            ->add('scheduledCommand', HiddenType::class)
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setRequired(['scheduledCommand']);
        $resolver->setDefaults([
            'data_class' => ScheduledCommandLimitRange::class,
        ]);
    }
}

我遇到了一个问题,当我想提交此表单时,CommandLimitRange parentId 为空,所以我尝试将子表单的父 ID 作为隐藏字段传递给子表单。但是提交后还是有报错:

Cannot read index "0" from object of type "Synolia\SyliusSchedulerCommandPlugin\Entity\ScheduledCommand" because it doesn't implement \ArrayAccess.

将父实体 ID 传递到条目中以便在提交正确的 parentId 后链接到数据库中的行的正确方法是什么? 非常感谢

【问题讨论】:

    标签: forms symfony doctrine


    【解决方案1】:

    我找到了我的解决方案。好的,所以这里有几个问题,我以前没有清楚地理解。 首先也是最重要的 - 我只有基本的 setter,而不是添加/删除方法。

    public function addCommandLimitRange(ScheduledCommandLimitRange $commandLimitRange): self
        {
            if (!$this->commandLimitRanges->contains($commandLimitRange)) {
                $this->commandLimitRanges[] = $commandLimitRange;
                $commandLimitRange->setScheduledCommand($this);
            }
    
            return $this;
        }
        public function removeCommandLimitRange(ScheduledCommandLimitRange $commandLimitRange): self
        {
            if ($this->commandLimitRanges->removeElement($commandLimitRange)) {
                // set the owning side to null (unless already changed)
                if ($commandLimitRange->getScheduledCommand() === $this) {
                    $commandLimitRange->setScheduledCommand(null);
                }
            }
    
            return $this;
        }
    

    接下来我需要在构造函数中将我的属性设为 ArrayCollection 对象:

    public function __construct()
        {
            $this->commandLimitRanges = new ArrayCollection();
        }
    

    最后为了得到正确的删除,而不是在 parentId 上使用 null 运行更新,我需要将 orphan_removal 选项添加到注释中。

    /**
         * @ORM\OneToMany(targetEntity="ScheduledCommandLimitRange", mappedBy="scheduledCommand", cascade={"persist"}, orphanRemoval=true)
         */
        private $commandLimitRanges;
    

    【讨论】:

      猜你喜欢
      • 2019-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多