Symfony和Doctrine模板 - 建立一对多的关系

在我的数据库模式中,我有几个与父表相关的表。解决关系问题的“丑陋”方法是在模式中手动包含依赖项:
sfArea:
  columns:
    id: integer
    name: string

sfCity:
  columns:
    name: string        
    area_id: integer
  relations:
    Area:
      class: sfArea
      local: area_id
      foreignType: many
      foreignAlias: Cities

sfItem:
  columns:
    name: string
    area_id: integer
  relations:
    Area:
      class: sfArea
      local: area_id
      foreignType: many
      foreignAlias: Items
但是,每次我要添加一个要附加到该区域的类时,我都需要添加关系以及随之而来的所有行(copy / paste => future hell)。这是我决定使用Doctrine_Template的地方,它允许我实现同样的事情:
sfArea:
  columns:
    id: integer
    name: string

sfCity:
  actAs:
    AreaRelated: { foreignAlias: Cities }
  columns:
    name: string        

sfItem:
  actAs:
    AreaRelated: { foreignAlias: Items }
  columns:
    name: string
和模板类:
class AreaRelated extends Doctrine_Template
{
    protected $_options = array(
        'foreignAlias'  =>  ''
    );

    public function setTableDefinition()
    {
        $this->hasColumn('area_id', 'integer');
    }

    public function setUp()
    {
        $this->hasOne('sfArea as Area', array(
                'local' => 'area_id',
                'foreign' => 'id',
                'foreignType' => 'many',
                'foreignAlias' => $this->_options['foreignAlias']
            )
        );
    }
}
表格生成正确,关系在$ sfCity-> Area方向上有效。但是,不应创建应在sfArea类中设置的关系($ sf_area-> Cities在“sfArea”上给出错误“未知记录属性/相关组件”城市“”)。 如何创建其他关系?我甚至尝试过(没有成功):
//...
public function setUp()
{
    $thisTable = $this->_table;
    $areaTable = Doctrine::getTable("smArea");

    $thisTable->hasOne('smArea as Area', array(
            'local' => 'area_id',
            'foreign' => 'id',
            'foreignType' => Doctrine_Relation::MANY
        )
    );        

    $areaTable->hasMany($thisTable->getOption('name') . ' as ' . $this->_options['foreignAlias'], array(
            'local' => 'id',
            'foreign' => 'area_id',
            'foreignType' => Doctrine_Relation::ONE
        )
    );             
}
    
已邀请:
不幸的是,如果没有至少一些额外的定义,我认为没有办法做到这一点。要做到这一点需要最少添加的一种方法是通过选项枚举区域上的关系:
Area:
  options:
    models_with_areas: [Cities, Items]
然后在
Area::setUp
中附上关系
public function setUp()
{
  parent::setUp();
  $models = $this->getTable()->getOption('models_with_areas');
  foreach($models as $model)
  {
    $this->hasMany($model, array(
         'local' => 'id',
         'foreign' => Doctrine_Inflector::tablize($model) . '_id'
    ));
  }
}
当然,这种方法是不灵活的,如果你想要更复杂的逻辑或选项,这种方法效果不是很好。您可以始终仅在区域上定义关系,但继续在关系的多个方面使用行为。 与其他一些答案相反,我确实认为这是一种合理的方法,可能是一个好主意。 Symfony / Doctrine哲学的核心原则是不要重复自己。这个解决方案坚持这个想法。如果在AreaRelated的类之间共享逻辑,它还提供了显着的好处。 *除了一个丑陋的:你可以遍历每个表并找到任何具有模板AreaRelated的表。这将需要在每次加载区域记录时实例化每个表,这听起来像一个绝对可怕的想法。     
到目前为止,为了记录,我最好的猜测是在模式文件中以手动方式进行。由于Nathan提到的模式变化很少,我认为如果行为无法实现(这将作为一个副项目继续尝试),这是最好的方法。行为方法的好处是它可以在依赖于该中心对象的所有对象上自动且一致地生成与特定非常中心对象的关系。 另一个可以使用的有用示例是例如多站点博客引擎,其中所有帖子,用户,类别,媒体上传......都与特定博客相关。
sfArea:
  columns:
    id: integer
    name: string

sfCity:
  columns:
    name: string        
    area_id: integer
  relations:
    Area:
      class: sfArea
      local: area_id
      foreignType: many
      foreignAlias: Cities

sfItem:
  columns:
    name: string
    area_id: integer
  relations:
    Area:
      class: sfArea
      local: area_id
      foreignType: many
      foreignAlias: Items
    
我认为你有一个很大的模型问题,在数据库上代表这种雇佣只会让你头疼不已。我正在为一个有类似东西的主要网站做一些捣蛋。 我的建议是,如果真的需要在数据库中存在,或者在建模Relational数据库时你正在考虑对象,那就考虑一下并重新分析。 使用您在示例中提供的信息,City和类似“类别”,因此如果您将它们放在参考表中,则可以对区域进行分类,从而最大限度地减少代码复制。一个类别可能有其他关系,或者只是一个包含大量字段的大表。 所以这是我建议的那种模型(推进):
Area:
  tableName: area_table
  description: Area
  columns:
    id:
    name:
    category_id:
      type: integer
      foreignClass: Category
      foreignReference: id
      required: true

Category
  tableName: categor_table
  description: An area specialization
  columns:
    id:
    model_class_name:
      type: varchar(255)
      description: the model Class that will represent this piece of information
    field1:
    field2:
    relation:1
使用mode_class_name作为提示知道如何处理原始数据,您可以执行以下操作:
CategoryClass >>
 public function getObjectRepresentation()
 {
   return new $this->getModelClassName()($this);
 }
[...]

RealObjectRepresentation1 >>
 public function __construct(Category $category)
 {
   //Initialize proper object using category information
 }
因此,您已将DatabaseHirearchy移至PhpObjectHirearchy 希望这在某种程度上有所帮助,如果您需要更多细节,我很乐意提供帮助!     

要回复问题请先登录注册