通过Symfony的表单生成器将新实体保存在按字段索引的一对多关联中



我花了很长时间才能正确获得标题,而我还没有写这个问题:/

这里:我的菜单是从实体加载的。为了允许用户将菜单转换为多种语言,我创建了一个与Menu通过ManyToOne关联关联的Menu实体和LocalizedMenu实体。

遵循此简短指南,我将与LocalizedMenu->locale字段的关联索引。这样可以确保数据库中每个语言环境只有一个LocalizedMenu,并且该学说覆盖了现有的语言。

这就是外观:

/**
 * @ORMEntity(repositoryClass="AppRepositoryMenuRepository")
 */
class Menu
{
    /**
     * @Groups({"menu"})
     * @ORMId
     * @ORMColumn(type="integer")
     * @ORMGeneratedValue(strategy="AUTO")
     */
    private $id;
    // ...
    /**
     * References translated menus.
     * @Groups({"localized_menus"})
     *
     * @ORMOneToMany(
     *     targetEntity="LocalizedMenu"
     *     ,mappedBy="parentMenu"
     *     ,indexBy="locale"
     *     ,cascade={"persist", "remove"}
     * )
     * @ORMOrderBy({"locale" = "ASC"})
     */
    private $localizedMenus;
    // ...
    public function getLocalizedMenu($locale) {
        if (!isset($this->localizedMenus[$locale])) {
            return new LocalizedMenu($locale, $this);
        }
        return $this->localizedMenus[$locale];
    }
    public function addLocalizedMenu($localizedMenu): self
    {
        $this->localizedMenus[$localizedMenu->getLocale()] = $localizedMenu;
        return $this;
    }
}

LocalizedMenu是一个持有用户翻译菜单字段的实体:

/**
 * @ORMEntity(repositoryClass="AppRepositoryLocalizedMenuRepository")
 */
class LocalizedMenu
{
    public function __construct($locale, $menu) {
        $this->locale = $locale;
        $this->parentMenu = $menu;
        $this->parentMenu->addLocalizedMenu($this);
    }
    // region FIELDS
    /**
     * @Groups({"localized_menu", "localized_menus"})
     * @ORMId
     * @ORMColumn(type="integer")
     * @ORMGeneratedValue(strategy="AUTO")
     */
    private $id;
    /**
     * @Groups({"localized_menu", "localized_menus"})
     * @var $locale string
     * @ORMColumn(
     *     type                 = "string"
     *     ,unique              = true
     * )
     */
    private $locale = "";
    /**
     * @Groups({"localized_menu", "localized_menus"})
     * @ORMColumn(
     *     type                 = "string",
     *     length               = 75
     * )
     */
    private $title = "";
    /**
     * @Groups({"localized_menu", "localized_menus"})
     * @var $description string Extra description for this menu item
     * @ORMColumn(
     *     type                 = "text",
     *     name                 = "description"
     * )
     */
    private $description = "";
    /**
     * @Groups({"localized_menu", "localized_menus"})
     * @ORMColumn(
     *     type                 = "datetime",
     *     name                 = "creation_date"
     * )
     * @AssertDateTime()
     */
    private $creationDate;
    /**
     * @Groups({"localized_menu", "localized_menus"})
     * @ORMColumn(
     *     type                 = "datetime",
     *     name                 = "edit_date"
     * )
     * @AssertDateTime()
     */
    private $editDate;
    /**
     * @Groups({"localized_menu", "localized_menus"})
     * @ORMColumn(type="text")
     * @AssertNotBlank(
     *     message = "Een menu item is een pagina die inhoud nodig heeft, vergeet dit niet"
     * )
     */
    private $content = "";
    /**
     * @var $parentMenu Menu Parent menu for this localized menu
     *
     * @Groups({"localized_menu", "localized_parent_menu"})
     * @ORMManyToOne(
     *     targetEntity="Menu",
     *     inversedBy="localizedMenus"
     * )
     */
    private $parentMenu;
}

要将所有这些都带给用户进行编辑,我创建了一个MenyType表格:

    $builder
        ->add('localizedMenus', CollectionType::class, array(
            'entry_type' => LocalizedMenuType::class,
            "entry_options" => [
                "choice_locale" => $options["choice_locale"]
            ],
            'allow_add' => true,
            'allow_delete' => true,
            'required' => false
        ))

LocalizedMenuType表格:

    $builder
        ->add('title', TextType::class, array(
            'label'             => 'Titel',
            'trim'              => true
        ))
        ->add('description', TextareaType::class, array(
            'label'             => 'Omschrijving',
            'trim'              => true
        ))
        ->add('content', TextareaType::class, array(
            'label'             => 'Inhoud',
            'trim'              => true,
            'attr'              => array('class' => 'tinymce'),
            'data'              => " "
        ))
        ->add('locale', LocaleType::class, array(
            "choice_translation_locale" => $options["choice_locale"]
        ))
    ;

i"思考"此逻辑是正确的,但是使用JavaScript创建新的LocalizedMenu表单后,我会得到此错误:

太少的参数无法函数app entity entainizedMenu :: __ construct(), 0通过 /users/robbievercammen/projects/web/base/vendor/symfony/form/form/extension/core/type/formtype.php 在第136行,正好2个预期

我如何使自己的表格优雅地使用逻辑?

编辑 - 真实问题

错误消息不是这里的真正错误。正如我之前说的,如果我删除了构造函数参数,它确实将记录保存到数据库中。即让学说使用协会将新的LocalizedMenu记录与Menu记录相关联。这就是数据库中的外观:

Menu

|id| //...
| 7| //...

LocalizedMenu

| id | locale | title   | description | creation_date       | edit_date           
| content | parent_menu_id |
----
|  4 | nl     | Contact | Contact     | 2019-02-21 14:02:47 | 2019-02-21 14:02:47 |
 Contact |           NULL |

问题是LocalizedMenu -> parent_menu_id是零。由于某种原因,我的设置不会为父菜单生成ID。下次从数据库获取菜单时,$menu->getLocalizedMenus()返回一个空数组,因为它们不正常。

遵循我提到的指南,这似乎是我告诉学说 $localizedMenu -> locale

索引的唯一方法

您的LocalizedMenu构造函数需要两个参数-$locale$menu。当Symfony为您的新提交的数据实例化新的LocalizedMenu实例时,它会直接进行new LocalizedMenu()填充其数据。

如果您需要自定义形式中的新/动态内容创建对象的方式(例如,当您具有constructor参数时),则必须在LocalizedMenuType类上设置empty_data选项。

请参阅https://symfony.com/doc/current/form/use_empty_data.html有关更多信息。

您的LocalizedMenu构造函数参数之一是菜单实例。此菜单实例将需要作为必需的选项传递给您的LocalizedMenuType

class LocalizedMenuType extends AbstractType
{
    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setRequired('menu');
        $resolver->setAllowedTypes('menu', Menu::class);
        $resolver->setDefault('empty_data', function (Options $options) {
            return new LocalizedMenu($options['choice_locale'], $options['menu']);
        });
    }
}

相关内容

  • 没有找到相关文章

最新更新