代码之家  ›  专栏  ›  技术社区  ›  canni

Yii框架“meta-db-model”创建+postgres继承

  •  0
  • canni  · 技术社区  · 15 年前

    我有几个DB表,它们是使用从一个表继承来构建的,这是一种用于创建新表的“模板”,现在我有了一组处理从模板继承的列的业务逻辑方法,其他列仅用作表示模型的参数,它们对逻辑没有任何意义。

    我们的目标是共享所有这些表的业务逻辑方法,我知道,现在可以通过添加另一个扩展CActiveRecord的类来完成,并从中扩展每个模型,或者将逻辑打包为行为并将其附加到模型中。

    有没有一种方法可以编写某种“元模型”作为参数、表名,或者某种方法可以“动态”为表创建模型并附加到it业务逻辑中?

    我在Yii用户板上问过这个问题,但没有找到任何答案:/ 我认为这是某种代码挑战,所以欢迎提供任何帮助/线索:)

    [编辑]

    一些样品: 不同客户端设备的表

    • hfc.U调制解调器
    • lan.switch_port
    • (在不久的将来,将有更多的“技术”添加到系统中,因此将为客户端设备提供新的表,并且有可能放弃对其中一些设备的支持)

    每个表都继承自模板表client\u device,其中包含以下字段:

    • 核心设备id
    • (加上一些元列,用于创建、更新、更新等可时间戳的行为)

    正如您所看到的,业务逻辑只在ID上运行,并且对于每个表都是相同的,其余的列用作设备参数存储/表示信息。

    我的目标是拥有“元模型”客户端设备,witch将业务逻辑应用于所有这些表,并且仍然为每个表提供对特定字段的访问,而不必为每个表编写模型类(每次添加新技术时,我都必须这么做,或者对特定技术的支持将在将来被放弃)

    1 回复  |  直到 15 年前
        1
  •  2
  •   thaddeusmt    15 年前

    好吧,如果我没听错的话,我有一个基于我正在做的类似事情的建议:

    我有一个基本的“特征”模型。但是特性可以是“文本”特性,也可以是“图像”特性等等,但是它们都共享公共的“特性id”和其他一些列。所以我采取了一种 EAV 接近。我有一个“feature”表,然后为每个子类型(文本、图像等)都有一个表。“feature”表中的一列包含子类型信息。然后在基本“feature”模型的“afterFind()”方法中,我查看子类型列。如果子类型是“文本”,我附加一个“文本”类型的行为。此行为从子类型表中获取变量,并将其设置为与基本模型的属性一样进行访问。

    像这样:

    :(基表)

    -服务id

    -设备类型(行为的名称,如CableModemBehavior或VoipGatewayBehavior)

    电缆\调制解调器\表
    -核心设备id
    -调制解调器信息\u 1
    -调制解调器\u到\u 2


    -核心设备id
    -网关信息\u 1
    -网关\u到\u 2

    在ClientDevice CActiveRecord模型(基本模型)中:

    protected function afterFind() {
      parent::afterFind();
      // remember $this->device_type holds the relevant behavior i.e. CableModemBehavior
      $this->attachBehavior($this->device_type,call_user_func(array($this->device_type, 'model')));
    }
    

    class CableModemBehavior extends CActiveRecordBehavior {
      public modem_info_1;
      public modem_info_2;
      public function attach($owner)
      {
        parent::attach($owner);
        $connection = Yii::app()->getDb();
        $command=$connection->createCommand("SELECT * 
          FROM cable_modem_table 
          WHERE core_device_id=:device_id");
        $command->bindParam(':device_id',$this->owner->core_device_id);
        $data=$command->queryRow();
        $this->modem_info_1 = $data->modem_info_1;
        $this->modem_info_2 = $data->modem_info_2;
      }
    }
    

    这是未经测试,但现在应该发生的是,如果你得到一个ClientDevice模型

    客户端设备->调制解调器信息\u 1

    当然,会有更多的事情发生。这只是为了“寻找”这个案子。你将需要做更多的工作来让mass属性赋值的东西为$\文章工作,或者传递关系,或者添加afterDelete,validate和afterSave方法来支持保存和删除,等等,但是我希望这是一个有用的开始。

    您还可以通过在行为中重写基本模型的\uuu get和\uu set方法使其更好,这样,如果请求子类型表中的某个列,它就会透明地从文本表中获取该列,执行模式查找以获取列名等,这比我在本例中所做的硬编码要好得多。在 yiiext 存储库和 AdvancedArBehavior

    干杯!