2012-03-05 121 views
4

3個模型映射3個表格:Image,Slider和SliderImageAssoc。在這種情況下,它是一對多的,因爲一個圖像可以「鏈接」到許多滑塊。我熟悉的ZF方式也提出了3種模型,並且在其中存儲特殊的內部數據時,可以執行像$ imageRow-> getSliderViaSliderImageAssoc()這樣的操作,從而生成滑塊的父級行某些Image模型。自定義Magento模型之間的多對多或一對多關係

我的問題是如何確切地提取Magento中的相關模型?我見過名爲setParentFieldName的方法,但我不認爲它們是核心的。你可以做這樣的事情:

foreach ($model->getCollection() as $model) { 
    $parentRow  = $model->getParent('some/model/name'); 
    $dependentRowset = $model->getChildren('some/other/model/name'); 
} 

PS:我不一定要使用ZF風格的抓取。

回答

7

就我所知,在Magento中不支持實體表關係的通用映射。我建議在資源模型和資源集合中添加輔助方法,以根據需要將選擇對象添加到選擇對象中。

下面是來自所提及的工具方法方法的核心的實例來加載在收集的附加數據:

// from Mage_Catalog_Model_Resource_Product_Collection::joinUrlRewrite() 
public function joinUrlRewrite() 
{ 
    $this->joinTable(
     'core/url_rewrite', 
     'entity_id=entity_id', 
     array('request_path'), 
     '{{table}}.type = ' . Mage_Core_Model_Url_Rewrite::TYPE_PRODUCT, 
     'left' 
    ); 

    return $this; 
} 

如果調用,core_url_rewrite表與產品實體表接合。

如果每次都需要加載加入的數據,則_getLoadSelect()方法可用於資源模型,或_initSelect()用於收集。
下面是從cms/page資源模型的例子:

// from Mage_Cms_Model_Resource_Page::_getLoadSelect() 
protected function _getLoadSelect($field, $value, $object) 
{ 
    $select = parent::_getLoadSelect($field, $value, $object); 

    if ($object->getStoreId()) { 
     $storeIds = array(Mage_Core_Model_App::ADMIN_STORE_ID, (int)$object->getStoreId()); 
     $select->join(
      array('cms_page_store' => $this->getTable('cms/page_store')), 
      $this->getMainTable() . '.page_id = cms_page_store.page_id', 
      array()) 
      ->where('is_active = ?', 1) 
      ->where('cms_page_store.store_id IN (?)', $storeIds) 
      ->order('cms_page_store.store_id DESC') 
      ->limit(1); 
    } 

    return $select; 
} 

_initSelect()一個例子聯接可在Mage_CatalogInventory_Model_Resource_Stock_Item_Collection::_initSelect()發現(我就不會在這裏發佈它,因爲它是如此的相似例如_getLoadSelect())。

某些模塊設置來自模塊「外部」的集合的連接,即庫存項目集合Mage_CatalogInventory_Model_Resource_Stock_Item::addCatalogInventoryToProductCollection($productCollection)。這裏cataloginventory模塊使用產品集合選擇對象來添加一些連接的數據。

最後,另一種方法是加載所需要的數據在_afterLoad()方法做單獨的選擇(相比於加入):

// from Mage_Cms_Model_Resource_Page_Collection::_afterLoad() 
protected function _afterLoad() 
{ 
    if ($this->_previewFlag) { 
     $items = $this->getColumnValues('page_id'); 
     $connection = $this->getConnection(); 
     if (count($items)) { 
      $select = $connection->select() 
        ->from(array('cps'=>$this->getTable('cms/page_store'))) 
        ->where('cps.page_id IN (?)', $items); 

      if ($result = $connection->fetchPairs($select)) { 
       foreach ($this as $item) { 
        if (!isset($result[$item->getData('page_id')])) { 
         continue; 
        } 
        if ($result[$item->getData('page_id')] == 0) { 
         $stores = Mage::app()->getStores(false, true); 
         $storeId = current($stores)->getId(); 
         $storeCode = key($stores); 
        } else { 
         $storeId = $result[$item->getData('page_id')]; 
         $storeCode = Mage::app()->getStore($storeId)->getCode(); 
        } 
        $item->setData('_first_store_id', $storeId); 
        $item->setData('store_code', $storeCode); 
       } 
      } 
     } 
    } 

    return parent::_afterLoad(); 
} 

這可以使用一個*_load_after事件也做了集合或楷模。

+0

您能否更具體地瞭解在覈心中哪裏可以找到這些示例? – nevvermind 2012-03-05 13:00:32

+0

增加了答案的例子。 – Vinai 2012-03-05 15:23:16

+0

非常好。謝謝。 – nevvermind 2012-03-05 15:52:17