【问题标题】:Magento resource model for table with compound primary key具有复合主键的表的 Magento 资源模型
【发布时间】:2010-06-09 18:48:59
【问题描述】:

我正在为 Magento 电子商务网站创建一个自定义模块,该模块将围绕一个具有复合/复合主键的新(即自定义)表,或者更确切地说,该表有两列构成主键钥匙。有人知道如何根据带有复合键的表创建模型/资源模型吗?

为了提供更多细节,我查阅了几个教程,还使用了出色的 moduleCreator 脚本。但似乎所有的教程都围绕着一个只有一列的 PK 表。像这样的:

class <Namespace>_<Module>_Model_Mysql4_<Module> extends Mage_Core_Model_Mysql4_Abstract {
   public function _construct(){
        $this->_init('<module_alias>/<table_alias>', '<table_primary_key_id>');
   }
} 

另外,我刚刚注意到,查看数据库模型时,几乎所有表都有一个主键。我知道这与 EAV 风格的数据库结构有很大关系,但是仍然可以使用带有复合 PK 的表吗?如果可能的话,我想坚持使用 Magento 框架/约定。是不是气馁了?我是否应该将自定义表的结构更改为具有一些虚拟 id 列?我确实有能力做到这一点,但是天哪!

(我想我会提到的另一个注意事项是,Zend 框架似乎提供了一种将类基于具有复合主键(see Example #20 on this page - 大约一半)的表的方法,所以看起来Magento 框架也应该提供它......我只是不明白如何。)

【问题讨论】:

    标签: php zend-framework data-structures magento


    【解决方案1】:

    与大多数受 Active Record 启发的模型一样,Magento 的 Mage_Core_Model_Abstract 在构建时并未考虑到对复合主键的支持。从这个基础继承的任何模型(意味着所有模型)都会继承这个假设。如果您想使用复合主键,您将无法使用。您的选择是走 Magento 模型路线并创建一个主键(“假”,如您所说),然后将唯一索引应用于表,或者使用基本 Zend DB 表实现您自己的模型层,或者导入支持您想要的功能的系统中的第三方模型解决方案。

    就 Zend 框架而言,Magento 团队使用 Zend 的Table Gateway Pattern to implement an Active Record style Model layer 作为他们的框架。 Zend Framework 不是像 Cake 或 Rails 那样的应用程序堆栈,它是可用于构建应用程序堆栈(或应用程序,或许多其他东西)的类库的集合。仅仅因为 Zend Framework 类支持某些东西并不意味着使用 Zend Framework 的系统和应用程序可以免费获得它。

    【讨论】:

    • 艾伦,你的答案总是很出色。
    • 如果 magento 2 不可能,那么您能解释一下 magento 如何保存 cms_block_store 表数据吗?我遇到了同样的问题。
    【解决方案2】:

    看到magento模型“Mage_SalesRule_Model_Resource_Coupon_Usage”,表“salesrule_coupon_usage”有一个复合/复合主键。是这样的:

    protected function _construct()
    {
        $this->_init('salesrule/coupon_usage', '');
    }
    

    【讨论】:

    • 即使这是正确的,这也无济于事。 salesrule/coupon_usage 根本没有模型,只有资源模型。只要你有一个空的idFieldName 和一个模型,你就完蛋了。
    【解决方案3】:

    虽然您可能无法在标准 Active Record 样式模型中使用复合主键,但可以通过将每个字段设置为主要字段来轻松地在支持的数据库迁移中创建复合主键;

    /**
     * Create table 'cms/block_store'
     */
    $table = $installer->getConnection()
        ->newTable($installer->getTable('cms/block_store'))
        ->addColumn('block_id', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(
            'nullable'  => false,
            'primary'   => true,
            ), 'Block ID')
        ->addColumn('store_id', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(
            'unsigned'  => true,
            'nullable'  => false,
            'primary'   => true,
            ), 'Store ID')
        ->addIndex($installer->getIdxName('cms/block_store', array('store_id')),
            array('store_id'))
        ->addForeignKey($installer->getFkName('cms/block_store', 'block_id', 'cms/block', 'block_id'),
            'block_id', $installer->getTable('cms/block'), 'block_id',
            Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)
        ->addForeignKey($installer->getFkName('cms/block_store', 'store_id', 'core/store', 'store_id'),
            'store_id', $installer->getTable('core/store'), 'store_id',
            Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)
        ->setComment('CMS Block To Store Linkage Table');
    $installer->getConnection()->createTable($table);
    

    【讨论】:

      【解决方案4】:

      我知道这是一个老问题,但我遇到了同样的问题,但我在这里是如何解决的:我添加了所有用逗号分隔的字段:

      protected function _construct()
      {
          $this->_init('salesrule/coupon_usage', 'first_field,second_field,...');
      }
      

      【讨论】:

      • 这仅在保存具有主要值的对象时才有效。它显然对加载或删除没有帮助。标准资源模型不是这样设计的,它只能靠运气发挥作用。
      猜你喜欢
      • 2012-02-17
      • 2011-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-30
      • 1970-01-01
      • 1970-01-01
      • 2013-04-01
      相关资源
      最近更新 更多