先决条件:
我想知道是否可以覆盖从特征中获取的属性关联映射的inversedBy
属性。
我用作具体用户实体占位符的接口:
ReusableBundle \ ModelEntrantInterface.php
interface EntrantInterface
{
public function getEmail();
public function getFirstName();
public function getLastName();
}
User
实现EntrantInterface
的实体以及从AppBundle
中的这些抽象类派生的所有其他实体:ReusableBundle \实体\ Entry.php
/**
* @ORM\MappedSuperclass
*/
abstract class Entry
{
/**
* @var EntrantInterface
*
* @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface", inversedBy="entries")
* @ORM\JoinColumn(name="user_id")
*/
protected $user;
// getters/setters...
}
ReusableBundle \实体\ Timestamp.php
/**
* @ORM\MappedSuperclass
*/
abstract class Timestamp
{
/**
* @var EntrantInterface
*
* @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface", inversedBy="timestamps")
* @ORM\JoinColumn(name="user_id")
*/
protected $user;
// getters/setters...
}
并结合使用EntranInterface
UserAwareTrait
可以在多个实体之间重复使用:ReusableBundle \实体\性状\ UserAwareTrait.php
trait UserAwareTrait
{
/**
* @var EntrantInterface
*
* @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface")
* @ORM\JoinColumn(name="user_id")
*/
protected $user;
// getter/setter...
}
在Doctrine 2.6中,如果我要使用超类并希望覆盖其属性,我就这样做:
/**
* @ORM\MappedSuperclass
* @ORM\AssociationOverrides({
* @ORM\AssociationOverride({name="property", inversedBy="entities"})
* })
*/
abstract class Entity extends SuperEntity
{
// code...
}
但是,如果我希望该实体使用UserAwareTrait
并覆盖属性的关联映射...
/**
* @ORM\MappedSuperclass
* @ORM\AssociationOverrides({
* @ORM\AssociationOverride({name="user", inversedBy="entries"})
* })
*/
abstract class Entry
{
use UserAwareTrait;
// code...
}
...并运行php bin/console doctrine:schema:validate
我在控制台中看到此错误:
[学说\ ORM \映射\ MappingException]
名为' user'的字段覆盖无效。 for class' ReusableBundle \ Entity \ Entry'。
我是否有可以遵循的解决方法来达到预期效果?
使用特征存储共享属性
在使用该特征的类中覆盖关联映射或(可能)属性映射
答案 0 :(得分:2)
TL; DR 您应该将访问修改器从protected
更改为private
。不要忘记,你将无法直接操作子类中的私有属性,并且需要一个getter。
由于AnnotationDriver
中的错误(我相信或行为的怪癖)而出现异常。
foreach ($class->getProperties() as $property) {
if ($metadata->isMappedSuperclass && ! $property->isPrivate()
||
...) {
continue;
}
它跳过MappedSuperclass
的所有非私有属性,让它们在子类解析上组合元数据。但是当涉及到覆盖驱动程序试图在MappedSuperclass
级别执行时,它不记得该属性被跳过,无法在元数据中找到它并引发异常。
我在the issue做了详细解释。您还可以找到突出显示案例的单元测试的链接。
答案 1 :(得分:0)
您必须在自己的代码中尝试使用此功能才能看到,但可能可能。
作为一项实验,我在课程中覆盖了特征,然后使用class_uses()
http://php.net/manual/en/function.class-uses.php
<?php
trait CanWhatever
{
public function doStuff()
{
return 'result!';
}
}
class X
{
use CanWhatever;
public function doStuff()
{
return 'overridden!';
}
}
$x = new X();
echo $x->doStuff();
echo "\n\$x has ";
echo (class_uses($x, 'CanWhatever')) ? 'the trait' : 'no trait';
输出:
overridden!
$x has the trait
您可以在此处看到https://3v4l.org/Vin2H
然而,Doctrine Annotations仍然可以从特性而不是被覆盖的方法中获取DocBlock,这就是为什么我无法给出明确的答案。你只需要试一试,看看!
答案 2 :(得分:0)
我有一个类似的问题并通过覆盖它自己的属性来解决它:
<button md-raised-button type="submit" [disabled]="!myForm.get('emailPass').valid">Siguiente</button>