这创建模型之前,我们需要明确地定义将要创建的模型的类型和个数,就我们的礼品登记插件这个例子来说,看起来需要两种不同的模型:
- Registry Model:这个模型用于存储礼品登记信息,如礼品登记类型、地址和收件人信息
- Registry Item:这个模型用于存储每个登记的礼品的信息,如需要的数量、购买的数量和产品ID等
尽管这种方法没错,但并没有满足这个插件的所有需求,如果将所有信息存储在一张表中,只要添加更多的登记类型就需要修改代码。所以本例中最好将数据分别存放在多个表中:
- Registry Entity:此表用于存储礼品登记信息以及事件信息
- Registry Type:通过将礼品登记类型放到一个单独的表中,可以添加或删除事件类型
- Registry Item:本表用于存储每个登记的礼品的信息,如需要的数量、购买的数量和产品ID等
确定好了数据结构,就可以开始创建获取各操作数据的相关模型了。
创建模型
我们首先来创建礼品登记的类型模型,用于管理登记类型,如婚礼、生日、小孩满月等礼品类型。要创建这一模型,应按照如下步骤来完成:
- 在我们的模块目录中找到Model文件夹
- 创建一个名为Type.php的文件,并将如下内容拷贝到文件中(app/code/local/Mdg/Giftregistry/Model/Type.php)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?php class Mdg_Giftregistry_Model_Type extends Mage_Core_Model_Abstract { public function __construct() { $this ->_init( 'mdg_giftregistry/type' ); parent::__construct(); } } |
我们还需要创建一个资源类,每个Magento的Data模型都有自己的资源类。另外不管是简单数据模型还是EAV模型这类直接处理数据的模型都要包含一个资源类,这需要按如下步骤来完成:
- 在我们的模块目录中找到Model文件夹
- 在Model下创建一个名为Mysql4的文件夹
- 创建一个名为Type.php的文件并将下面的代码拷贝到该文件中(app/code/local/Mdg/Giftregistry/Model/Mysql4/Type.php)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?php class Mdg_Giftregistry_Model_Mysql4_Type extends Mage_Core_Model_ Mysql4_Abstract { public function __construct() { $this ->_init( 'mdg_giftregistry/type' , 'type_id' ); } } |
最后,我们需要创建一个用于获取所有可用事件类型的collection类:
- 在我们的模块目录中找到刚刚创建的Mysql4文件夹
- 在Mysql4文件夹下创建一个Type文件夹,然后再文件夹内创建一个名为Collection.php的文件(app/code/local/Mdg/Giftregistry/Model/Mysql4/
Type/Collection.php)并拷入如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class Mdg_Giftregistry_Model_Mysql4_Type_Collection extends Mage_ Core_Model_Mysql4_Collection_Abstract { public function __construct() { $this ->_init( 'mdg_giftregistry/type' ); parent::_construct(); } } |
下面我们再创建一个处理礼品登记产品的模型,该模型存放所有与商品有关的产品信息,具体步骤如下:
- 在模块目录下找到Model文件夹
- 创建一个全新的Item.php文件,并将事下代码拷入该文件中(app/code/local/Mdg/Giftregistry/Model/Item.php):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class Mdg_Giftregistry_Model_Item extends Mage_Core_Model_Abstract { public function __construct() { $this ->_init( 'mdg_giftregistry/item' ); parent::_construct(); } } |
下一步创建资源类:
- 进入模块中的Model文件夹
- 打开Mysql4文件夹
- 创建一个全新的Item.php并将如下代码拷入该文件中(app/code/local/Mdg/Giftregistry/Model/Mysql4/
Item.php):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class Mdg_Giftregistry_Model_Mysql4_Item extends Mage_Core_Model_ Mysql4_Abstract { public function __construct() { $this ->_init( 'mdg_giftregistry/item' , 'item_id' ); } } |
最后创建一个对应的集合类:
- 找到本模块下的Model文件夹
- 创建一个Collection.php文件,并将以下代码拷入该文件中(app/code/local/Mdg/Giftregistry/Model/
Mysql4/Item/Collection.php)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class Mdg_Giftregistry_Model_Mysql4_Item_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract { public function __construct() { $this ->_init( 'mdg_giftregistry/item' ); parent::_construct(); } } |
下一步创建Registry实体,这是礼品登记插件的重要组成部分,因为它是将所有文件整合在一起的模型,要实现这点需按如下步骤进行操作:
- 找到本模块下的Model文件夹
- 创建一个Entity.php文件,并将如下代码拷入文件中(app/code/local/Mdg/Giftregistry/Model/
Entity.php)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class Mdg_Giftregistry_Model_Entity extends Mage_Core_Model_Abstract { public function __construct() { $this ->_init( 'mdg_giftregistry/entity' ); parent::_construct(); } } |
然后再创建resource类
- 找到本模块中的Model文件夹
- 打开Mysql4目录
- 创建一个名为Entity.php的文件并将如下代码拷入该文件中(app/code/local/Mdg/Giftregistry/Model/
Mysql4/Entity.php)
1 2 3 4 5 6 7 8 9 10 11 12 13 | class Mdg_Giftregistry_Model_Mysql4_Entity extends Mage_Core_Model_Mysql4_Abstract { public function __construct() { $this ->_init( 'mdg_giftregistry/entity' , 'entity_id' ); } } |
然后创建一个对应的collection类:
- 找到本模块下的Model文件夹
- 创建一个Collection.php并如下代码(app/code/local/Mdg/Giftregistry/Model/
Mysql4/Entity/Collection.php)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class Mdg_Giftregistry_Model_Mysql4_Entity_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract { public function __construct() { $this ->_init( 'mdg_giftregistry/entity' ); parent::_construct(); } } |
以上我们加入了大量代码来为这一模块加入了多个模型类,下面让我们通过IMC(Interactive Magento Console,安装方法参见Magento ORM与数据集合一节)来测试一下这个新创建的模型。首先在Magento安装目录下输入如下指令来打开IMC测试我们上面创建的模型:
php shell/imc.php
以下假设您安装了测试数据或者已经拥有了相关数据:
- 首先加载客户模型
1
magento >
$customer
= Mage::getModel(
'customer/customer'
)->load(1);
- 其次实例化一个新的礼品登记对象:
1
magento >
$registry
= Mage::getModel(
'mdg_giftregistry/entity'
);
- Magento自带模型中有一个较为易用的方法getData(),它返回一个所有对象属性的数组,下面在礼品登记和客户两个对象中分别运行这个方法来对比输出结果
123
magento > print_r(
$customer
->getData());
magento > print_r(
$registry
->getData());
- 您可能已经注意到,customer对象返回示例客户的数据集,而registry对象返回一个穿宽的$regiarray数组,我们再来试试如下代码:
1234567891011
magento >
$registry
->setCustomerId(
$customer
->getId());
magento >
$registry
->setTypeId(1);
magento >
$registry
->setWebsiteId(1);
magento >
$registry
->setEventDate(
'2012-12-12'
);
magento >
$registry
->setEventCountry(
'CA'
);
magento >
$registry
->setEventLocation(
'Toronto'
);
- 下面能过如下代码尝试再次打印registry数据
1
magento > print_r(
$registry
->getData());
- 最后,为了让更改生效,调用模型save方法
1 | magento > $registry ->save(); |
但是会发现在保存产品时出现了报错,报错信息如下:
1 2 3 | Fatal error: Call to a member function beginTransaction() on a nonobject in …/app/code/core/Mage/Core/Model/Abstract.php on line 313 |
究竟是什么原因呢?所调用的save()方法是父类Mage_Core_Model_Mysql4_Abstract中的一部分,该类又会调用抽象类save()方法,但在config.xml配置文件中却缺少了一个重要内容。要让Magento正确识别要使用的是哪一个资源类,我们需要指定资源模型类以及每个实体相匹配的数据表。下面就对该配置文件进行相应的修改:
- 找到插件下的etc/文件夹
- 打开config.xml配置文件
- 使用如下代码对>model>节点进行修改(app/code/local/Mdg/Giftregistry/etc/config.xml)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | ... <models> <mdg_giftregistry> < class >Mdg_Giftregistry_Model</ class > <resourceModel>mdg_giftregistry_mysql4</resourceModel> </mdg_giftregistry> <mdg_giftregistry_mysql4> < class >Mdg_Giftregistry_Model_Mysql4</ class > <entities> <entity> <table>mdg_giftregistry_entity</table> </entity> <item> <table>mdg_giftregistry_item</table> </item> <type> <table>mdg_giftregistry_type</table> </type> </entities> </mdg_giftregistry_mysql4> </models> ... |
在将产品保存到数据库中之前,我们要先在数据库中创建表格,然后学习如何使用结构资源来创建所需的表结构并建立默认数据。这部分内容将在下一节Magento结构资源来进行探讨。