原则覆盖关系访问器


Doctrine override relation accessor

假设您有以下关系(为简单起见进行了更改):

Dog:
  columns:
    id:         { type: integer, notnull: true, primary: true }
    name:       { type: string,  notnull: true }
AwardType:
  columns:
    id:         { type: integer, notnull: true, primary: true }
    name:       { type: string,  notnull: true }
Award:
  columns:
    dog_id:     { type: integer, notnull: true, primary: true }
    award_id:   { type: integer, notnull: true, primary: true }
    is_granted: { type: boolean, notnull: true, default: false }
  relations:
    Dog:
      local:        dog_id
      foreign:      id
      type:         one
      foreignType:  many
      foreignAlias: Awards
    AwardType:
      local:        award_id
      foreign:      id
      type:         one
      foreignType:  many
      foreignAlias: Awards

通过上述设置,我可以添加一只新狗并手动为该狗添加奖励。我还可以编辑已经授予狗的奖励。

当我调用$myDog->getAwards()时,我希望该集合包括所有已授予的奖励(Award.is_granted==true &&Award.dog_id==$myDog()->getId())以及尚未授予该狗的所有奖励。

是否有可以在某处的模型中设置选项来实现这一点?如果没有,实现它的最佳方法是什么?

我正在使用Symfony 1.4和捆绑的Doctrine 1.2 ORM。

[ 编辑 1 ]
我意识到我没有正确解释整个奖项的事情,所以我会尝试扩展它。假设您有以下奖项类型:

  • 1:不骚扰邮递员的骨头
  • 2:不咬莫莉小姐的项圈
  • 3:追逐送奶工的更大骨头(我们都知道他是邪恶的)

Dog1 已注册并已获得奖项类型 1 和 3。编辑该狗时,表单应显示带有选中复选框的奖励类型 1 和 3,以及带有未选中复选框的奖励类型 2。如果狗 1 在奖励表中为每个奖励类型都有一个条目,这非常有用。两个is_granted == 真,一个is_granted == 假。目前为止,一切都好。

当用户输入新的 Dog 时,表单应显示所有奖励类型,但没有选中的复选框。保存新狗时,奖励表中应总共显示 3 行,并根据复选框的选中状态设置is_granted标志。

我知道我可以获得所有奖励类型,并根据奖励类型检查狗是否已被授予(显示所有未选中的新狗,授予已检查 + 尚未授予未选中的现有狗)。我在这里要问的是,教义是否有一些魔力,可以给我上面描述的复合集。

好的,

您在数据建模时遇到问题。它可能应该是这样的:

Dog:
  columns:
    id:         { type: integer, notnull: true, primary: true }
    name:       { type: string,  notnull: true, unique: true }
  relations:
    Awards:
      class: Award
      foreignType: many
      type: many
      refClass: DogAward
      local: dog_id
      foreign: award_id
Award:
  columns:
    id:         { type: integer, notnull: true, primary: true }
    name:       { type: string,  notnull: true, unique: true }
DogAward:
  columns:
    dog_id:     { type: integer, notnull: true, primary: true }
    award_id:   { type: integer, notnull: true, primary: true }

我使用了多对多关系,并添加了一些我认为可能对您的情况有用的约束。Symfony应该生成一个看起来像你想要的表单,如果不是这样,请告诉我们。

您可以在 lib/model/dog 中覆盖方法getAwards()方法.class.php

例如

public function getAwards(){
  return $query = $this->getTable()
    ->createQuery('a')
    ->where('a.dog_id = ?', $this->getId())
    ->addWhere('a.is_granted = ?', true);
    ->execute();
}

请注意,这只是一个模型,我现在没有测试它