如何在Symfony2中创建与Doctrine2的动态实体关联 [英] How to Create Dynamic Entity Association with Doctrine2 in Symfony2

查看:164
本文介绍了如何在Symfony2中创建与Doctrine2的动态实体关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建CMS,具有动态路由,版本控制系统和多种不同的内容类型,例如文章,档案等我有一个ContentType实体,存储视图可以使用的所有可用的内容类型。但是该内容类型实例的数据将存储在一个单独的实体中(因为这些字段对于每种类型的内容都是唯一的,因此它不能全部适用于 ViewVersion ) 。

I am building a CMS, with dynamic routing, a versioning system, and multiple different content types, e.g. Article, Profile, etc. I have a ContentType entity that stores all the available content types that a View can be. But the data for that content type instance will be stored in a separate entity (since the fields are unique for each type of content so it can't all fit in the ViewVersion).

Routing --> View --> ViewVersion --> Article
or
Routing --> View --> ViewVersion --> Profile

Routing A --ManyToOne--> View D
Routing B --ManyToOne--> View D
Routing C --ManyToOne--> View D

View D --> ManyToOne -> ContentType (define what type this view is)
View D --> OneToOne --> Settings

View D --OneToMany--> ViewVersion E
View D --OneToMany--> ViewVersion F
View D --OneToMany--> ViewVersion G (*published version*)

ViewVersion E --OneToOne--> Article E
ViewVersion F --OneToOne--> Article F
ViewVersion G --OneToOne--> Article G

有关应用程序工作流程的详细背景信息(仍然存在),您可以看到在我在这里的相关问题,在标题项目和结构的代码背景下。

For detailed background information about the workflow of the application (still in flux), you can see a description in my related question here, under the heading "Background of Project and Structure of Code".

这些内容类型中的每一个将具有不同的字段和功能,因此它们将被定义在唯一的包中并且它们需要存在于它们自己的单独实体中(具有唯一字段的数据库表)。

Each of these content types will have different fields and functionality, so they will be defined in unique bundles and they need to exist in their own separate entities (database tables with unique fields).

我的主控制器根据路由查看 > url,并加载正确的bundle控制器来组合页面(具有身体区域的唯一功能和模板)。

My main Controller finds the View based on the Routing url, and loads the right bundle controller to assemble the page (with unique functions and template for the body area).

路由 entity存储一个或多个指向 View 实体的URL。

视图实体是路线可以指向的基本占位符,然后指向多个版本,设置发布版本的ID。

The View entity is a basic placeholder that routes can point to, and it then points to multiple versions, and sets the id of the published version.

ViewVersion 具有HTML页面,元数据,设计shell,浏览器标题等的所有基本信息,但没有关于内容。新的用户编辑时保存新的 ViewVersion 。如果版本在30分钟内尚未保存。

The ViewVersion has all the basic information for an HTML page, metadata, design shell, browser title, etc, but nothing about the content. A new ViewVersion is saved when edited by a new user or if the version hasn't been saved in 30 minutes.

没有ContentType实体,它将是捆绑的实际实体,例如 Gutensite\ArticleBundle\Entity\Article Gutensite\ProfileBundle\Entity\Profile 等,将根据View-> ContentType集直接链接到ViewVersion(所以我们知道它是什么类型的实体)。 ContentType(例如Article)将OneToOne返回到ViewVersion的相应ID,例如。 Article-> viewVersionId(每个版本都有一个内容类型记录)。每次保存新的ViewVersion时,都会保存相应的ContentType(克隆所有实体关联)。它们基本上是一个记录,只是由于视图和多个内容类型之间的动态关系而被分割成不同的实体。

There is no ContentType entity, it will be an actual entity from a bundle, e.g. Gutensite\ArticleBundle\Entity\Article, Gutensite\ProfileBundle\Entity\Profile, etc and will be linked directly to the ViewVersion based on the View->ContentType set (so we know what type of entity it is). The ContentType (e.g. Article) will be OneToOne back to the corresponding id of the ViewVersion, e.g. Article->viewVersionId (each version has one content type record). Every time a new ViewVersion is saved, the corresponding ContentType is saved as well (clone all entity associations). They are essentially one record, just split into different entities because of the dynamic relationship between a view and multiple content types.

传统的ORM映射在ViewVersion和动态ContentType,因为内容可能是不同捆绑包中的几个不同实体之一,因此我无法映射到单个静态文章或配置文件实体。这个链接需要是动态的。

Traditional ORM mapping won't work between ViewVersion and the dynamic ContentType, because the content could be one of several different entities in different bundles, so I can't map to a single static Article or Profile entity. This linking needs to be dynamic.

我想设置关联,以便我可以轻松地调用$ viewVersion-> getContent()来获取内容类型字段,也可以使用formBuilder来为该实体加载正确的formType。

I would like to set the association so that I can easily call $viewVersion->getContent() to get the content type fields, and also use the formBuilder to load the right formType for that entity.

很容易为表单构建器关联正确的FormType:

It's easy to associate the right FormType for the form builder:

class ViewVersionType extends AbstractType
{

    public function getName()
    {
        return 'viewVersion';
    }

public function buildForm(FormBuilderInterface $builder, array $options)
{
        // Add all the regular Fields
        $builder->add(...);

        // Add Dynamic Content Type Association
        //Get the form type for the requested content type and merge with the default view form
        $viewVersion = $builder->getData();
        $view = $viewVersion->getEntity();

        $contentPath = $view->namespace_bundle.'\\Form\\Type\\'.$view->getContentType()->getBundle().'Type';
        $builder->add('content', new $contentPath, array(
           'label' => false
        ));
    }
}

但是最好的添加方式是什么ViewVersion和相关ContentType之间的动态映射?

href =http://symfony.com/doc/current/cookbook/doctrine/resolve_target_entity.html =nofollow noreferrer>解决目标实体,但这似乎不是最好的选择,加上你必须在orm配置中注册每个bundle是不理想的。

I read about Resolve Target Entities but that doesn't seem like the best option, plus you have to register each bundle in the orm config which is not ideal.

我还阅读了关于动态表单修改,但这并不是真正需要的,因为我的表单解决方案并没有解决实体映射的基本问题。

I also read about Dynamic Form Modification but that's not really necessary given my solution for forms and doesn't solve the basic problem of entity mapping.

我还阅读了关于通过事件订阅者进行动态映射

I also read about dynamic mapping via an event subscriber which seems like exactly what I need. I assume I would put the trait on the dynamic content type entity, to point BACK to the ViewVersion. Then I would se the mapping association between the two. But I still can't figure out how to access the data I need in that subscriber event, to correctly tell the ViewVersion about the Article or Profile entity. I haven't grasped the big picture of Symonfy's architecture yet, to know how everything is related, how to access the variables I need, and where to find the right documentation!

推荐答案

这里有些想法可能有帮助(或不):

Some thoughts here that might help ( or not ):

我感觉 ContentType 应该链接到查看不是 ViewVersion 。我不能想像同一视图的不同版本可以有不同的内容类型。视图应该有一定的类型和不同的版本。

I have a feeling that ContentType should be linked to View not ViewVersion. I can not imagine that different versions of the same view can have different content types. A view should have a certain type and different versions.

我不太明白为什么 View - > ContentType 将是OneToOne关系。我会说,有一组内容类型,每个视图被分配到一个 ContentType ,所以它似乎更像一个ManyToOne关系。

I can't quite get why View -> ContentType will be a OneToOne relation. I would say that there is a set of content types and each View is assigned to one ContentType so it seems more like a ManyToOne relationship.

我不会尝试按照每种内容类型进行捆绑。我会说你可以有一个博客包含不同的内容类型和视图。

I would not try to make a bundle per content type. I would say you can have a Blog bundle with different content types and views.

查看实体可以有一个 $ content_type_id 引用 ContentType 。 Doctrine使用延迟加载,当您加载查看实体,doctrine不会在乎什么 ContentType 它链接到但会知道该查看,当您需要链接的 ContentType 时,它将运行查询以获取它并链接正确的 ContentType 到您的查看

View entity can have a $content_type_id which references the id of the ContentType. Doctrine uses lazy loading and when you load the View entity, doctrine won't care what ContentType it is linked to but will be aware of the content_type_id of that View and whenever you need the linked ContentType it will run the query to fetch it and link the correct ContentType to your View.

我总是觉得最好通过查看 symfony bundles 的源代码获取想法,并查看结果如何。

I always find it best to get ideas by looking at the source code of symfony bundles and see how things are being structured.

这篇关于如何在Symfony2中创建与Doctrine2的动态实体关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆