草庐IT

php - Symfony2/Doctrine 在类表继承中间映射父类(super class)

coder 2023-12-30 原文

我目前的模型结构如下:

/**
 * @ORM\Entity
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="related_type", type="string")
 * @ORM\DiscriminatorMap({"type_one"="TypeOne", "type_two"="TypeTwo"})
 */
abstract class BaseEntity {

    ... (all the usual stuff, IDs, etc)

    /**
     * @ORM\OneToMany(targetEntity="Comment", mappedBy="baseEntity")
     */
    private $comments;
}

/**
 * @ORM\Entity
 */
class TypeOne extends BaseEntity {
    /**
     * @ORM\Column(type="string")
     */
    private $name;

    /**
     * @ORM\Column(type="string")
     */
    private $description;
}

/**
 * @ORM\Entity
 */
class TypeTwo extends BaseEntity {
    /**
     * @ORM\Column(type="string")
     */
    private $name;

    /**
     * @ORM\Column(type="string")
     */
    private $description;   
}

/**
 * @ORM\Entity
 */
class Comment {

    ... (all the usual stuff, IDs, etc)

    /**
     * @ORM\ManyToOne(targetEntity="BaseEntity", inversedBy="comments")
     */
    private $baseEntity;
}

这里的想法是能够将注释绑定(bind)到任何其他表。到目前为止这一切似乎都工作正常(当然,我仍在探索设计选项,所以可能有更好的方法来做到这一点......),但我注意到的一件事是子类有一些共同的领域我想进入一个共同的父类。我不想将它们向上移动到 BaseEntity 中,因为会有其他对象是 BaseEntity 的子对象,但不会有这些字段。

我考虑过在中间创建一个 MappedSuperclass 父类,如下所示:

/**
 * @ORM\MappedSuperclass
 */
abstract class Common extends BaseEntity {
    /**
     * @ORM\Column(type="string")
     */
    private $name;

    /**
     * @ORM\Column(type="string")
     */
    private $description;       
}

/**
 * @ORM\Entity
 */
class TypeOne extends Common {}

/**
 * @ORM\Entity
 */
class TypeTwo extends Common {}

我认为这可行,但原则数据库模式生成器提示我不能在 MappedSuperclass 上进行 OneToMany 映射。我没想到这会成为一个问题,因为 OneToMany 映射仍在根 BaseEntity 和 Comment 表之间。我是否应该使用不同的结构,或者是否有其他方法可以使这些字段通用而不将它们添加到 BaseEntity 上?

最佳答案

来自文档:

A mapped superclass is an abstract or concrete class that provides persistent entity state and mapping information for its subclasses, but which is not itself an entity. Typically, the purpose of such a mapped superclass is to define state and mapping information that is common to multiple entity classes.

也就是说,您如何将一个实体与另一个非实体相关联?

更多来自文档:

A mapped superclass cannot be an entity, it is not query-able and persistent relationships defined by a mapped superclass must be unidirectional (with an owning side only). This means that One-To-Many assocations are not possible on a mapped superclass at all. Furthermore Many-To-Many associations are only possible if the mapped superclass is only used in exactly one entity at the moment. For further support of inheritance, the single or joined table inheritance features have to be used.

来源:http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/inheritance-mapping.html


更新

因为您的 MappedSuperClass 扩展了 BaseEntity,所以它也继承了 BaseEntity 的关联,就好像它是它自己的关联一样。所以你实际上确实在 MappedSuperClass 上有一个 OneToMany。

要绕过它,嗯,您需要修改/扩展学说以按照您想要的方式工作。

就 native 功能而言,您有两个选择:

类表继承 您的 Common 类和生成的 DB 表示将具有公共(public)字段,而子类现在将仅具有特定于它们自己的字段。不幸的是,如果您只是为了对公共(public)字段进行分组而尝试对它们进行分组,那么这可能是对数据的错误陈述。

使通用成为一个实体 似乎所有映射的父类(super class)都是一个未在数据库中表示的实体。因此,改为将 common 设为 Entity 。缺点是您最终会得到一个数据库表,但您可以直接删除它。

我建议您重新审视您的数据,并确保您只对名称和用途都相同的字段进行分组。例如,一个 ComputerBox、一个 ShoeBox、一个 Man 和一个 Woman 可能都具有“height”属性,但在这种情况下,我不建议使用一个具有它们都继承自的“height”属性的 Common 类。相反,我会有一个 Box,其中包含 ComputerBox 和 ShoeBox 共有的字段,我会有一个 Person,其中有 Man 和 Woman 共有的字段。在那种情况下,类表继承或单表(如果您愿意)都可以完美地工作。

如果您的数据遵循该示例,请使用单表或类表继​​承。如果没有,我可能建议不要对字段进行分组。

关于php - Symfony2/Doctrine 在类表继承中间映射父类(super class),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12202375/

有关php - Symfony2/Doctrine 在类表继承中间映射父类(super class)的更多相关文章

  1. ruby - 为什么在类上调用 instance_eval() 时定义类方法? - 2

    Foo=Class.newFoo.instance_evaldodefinstance_bar"instance_bar"endendputsFoo.instance_bar#=>"instance_bar"putsFoo.new.instance_bar#=>undefinedmethod‘instance_bar’我的理解是调用instance_eval在对象上应该允许您为该对象定义实例变量或方法。但是在上面的例子中,当你在类Foo上调用它来定义instance_bar方法时,instance_bar变成了一个可以用“Foo.instance_bar”调用的类方法。很明显这段代码没

  2. ruby-on-rails - 这个 C 和 PHP 程序员如何学习 Ruby 和 Rails? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它

  3. ruby - 如何在数组中间插入一个数组? - 2

    我有一个Ruby数组[1,4]。我想在中间插入另一个数组[2,3],这样它就变成了[1,2,3,4]。我可以使用[1,4].insert(1,[2,3]).flatten实现这一点,但是有更好的方法吗? 最佳答案 您可以通过以下方式进行。[1,4].insert(1,*[2,3])insert()方法处理多个参数。因此,您可以使用splat运算符*将数组转换为参数。 关于ruby-如何在数组中间插入一个数组?,我们在StackOverflow上找到一个类似的问题:

  4. ruby-on-rails - 如何在关闭 cache_classes 的情况下使用来自中间件的域对象? - 2

    在rails开发环境中,cache_classes是关闭的,所以你可以修改app/下的代码,不用重启服务器就可以看到变化。不过,在所有环境中,中间件只会创建一次。所以如果我有这样的中间件:classMyMiddlewaredefinitialize(app)@app=appenddefcall(env)env['model']=MyModel.firstendend我在config/environments/development.rb中执行此操作:config.cache_classes=false#thedefaultfordevelopmentconfig.middleware.

  5. ruby-on-rails - 保存 PDFKit 中间件显示的 PDF 文件 - 2

    如果有人有兴趣将PDF文件保存在PDFKit中间件gem显示的文件系统中,那么这里是...重写middleware.rb文件的call方法。在覆盖中只需替换这一行:body=PDFKit.new(translate_paths(body,env),@options).to_pdf与pdf=PDFKit.new(translate_paths(body,env),@options)file=pdf.to_file('Your/file/name/path')Mymodel.my_method()#Youcanwriteyourmethodheretousethatfilebody=pdf

  6. ruby-on-rails - Rack 中间件和线程安全 - 2

    我的Rails4应用程序使用了一个自定义Rack中间件。如果客户端未提供有效信息(我'正在开发API)。因此,在每个请求之前它会更改这些header,并且在每个请求之后它会添加一个带有自定义媒体类型信息的自定义X-Something-Media-Typeheader。我想切换到Puma,因此我有点担心这种中间件的线程安全性。我没有使用实例变量,除了我们在每个中间件中遇到的常见@app.call一次,但即使在这里我也复制了一些我在RailsCasts的评论中读到的内容:definitialize(app)@app=appenddefcall(env)dup._call(env)endde

  7. ruby-on-rails - rails delete_if 使用哈希忽略当前文章(中间人) - 2

    我为你们准备了一个简单的。我想要一个特色内容部分,其中排除了当前文章所以这可以通过delete_if使用MiddlemanBlog:但是我使用的是中间人代理,所以我无法访问current_article方法...我有一个YAML结构,其中包含以下模拟数据(以及其他数据),文件夹设置如下:data>site>caseStudy>RANDOM-ID423536.yaml(由CMS生成)在每个yaml文件中,您会发现如下内容::id:2k1YccJrQsKE2siSO6o6ac:title:Heyplace我的config.rb看起来像这样data.site.caseStudy.eachdo

  8. ruby - 在类/模块中加载外部文件 - 2

    我有一个外部文件:path_to_external_file.rb带有一些类定义:classAsome_definitionsend我想在模块B中加载它,以便上面定义的类A可以称为B::A。我试过:classBload('path_to_external_file.rb')end但是A是在主环境中定义的,而不是在B中定义的:A#=>AB.constants#=>[]如何在某些类/模块中加载外部文件?编辑我是否应该将外部文件作为字符串读取,并在Class.new{...}中评估它们,然后在B中include该类? 最佳答案 你不能。至

  9. Ruby 正则表达式 - 用文本中间的空格替换点 - 2

    我有一个很长的文本,我想用空格替换其中的点,但只能在文本的中间。例如:Domain:...................google.com我需要这样:Domain:google.com我发现了这个用单个空格替换点的正则表达式:str.gsub!(/(?但这还不够,因为它会产生:Domain:google.com我需要保留与点一样多的空格。你会如何解决? 最佳答案 你快到了,你的正则表达式没问题,只需使用String#gsub的block版本计算替换匹配的长度:▶str='Domain:...................goo

  10. ruby - 使用 gem 自动添加 Rack 中间件 - 2

    我有一个提供一些Rack中间件的gem,让它工作的唯一方法是将它放在我的application.rb中config.middleware.use"TBBC::Editor::Middleware"当我的gem在应用程序Gemfile中使用时,如何才能自动使用此中间件? 最佳答案 如果您打算将您的gem用于Rails3,您可以提供一个Railtie。如果使用Rails,您可以自动加载它。假设您的gem名称是tbbc,将它放在lib/tbbc/railtie.rb中:moduleTBBCclassRailtie在lib/tbbc.rb中

随机推荐