5

カタログ/レイヤーモデルの関数 prepareProductCollection($collection) を上書きしたいです。

なぜなら、シンプルな商品だけを表示したいので、やりたいのです:

 public function prepareProductCollection($collection)
    {
        $collection
           ->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
           ->addMinimalPrice()
           ->addFinalPrice()
           ->addTaxPercents()
           ->addUrlRewrite($this->getCurrentCategory()->getId());

        Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($collection);
        Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection);

        $collection
         ->addAttributeToSelect('type_id')
         ->addAttributeToFilter('type_id','simple');
       echo $collection->getSelect()->__toString();

    }

しかし、私がそれを行うと、このエラーが発生します:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'e.type_id' in 'where clause'

Trace:
#0 /Users/Ditchou/Documents/ProjetsWeb/lolote/lib/Varien/Db/Statement/Pdo/Mysql.php(110): Zend_Db_Statement_Pdo->_execute(Array)
#1 /Users/Ditchou/Documents/ProjetsWeb/lolote/lib/Zend/Db/Statement.php(300): Varien_Db_Statement_Pdo_Mysql->_execute(Array)
#2 /Users/Ditchou/Documents/ProjetsWeb/lolote/lib/Zend/Db/Adapter/Abstract.php(479): Zend_Db_Statement->execute(Array)
#3 /Users/Ditchou/Documents/ProjetsWeb/lolote/lib/Zend/Db/Adapter/Pdo/Abstract.php(238): Zend_Db_Adapter_Abstract->query('SELECT FLOOR((R...', Array)
#4 /Users/Ditchou/Documents/ProjetsWeb/lolote/lib/Varien/Db/Adapter/Pdo/Mysql.php(419): Zend_Db_Adapter_Pdo_Abstract->query('SELECT FLOOR((R...', Array)
#5 /Users/Ditchou/Documents/ProjetsWeb/lolote/lib/Zend/Db/Adapter/Abstract.php(808): Varien_Db_Adapter_Pdo_Mysql->query(Object(Varien_Db_Select), Array)
#6 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Catalog/Model/Resource/Layer/Filter/Price.php(274): Zend_Db_Adapter_Abstract->fetchPairs(Object(Varien_Db_Select))
#7 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Catalog/Model/Layer/Filter/Price.php(158): Mage_Catalog_Model_Resource_Layer_Filter_Price->getCount(Object(Mage_Catalog_Model_Layer_Filter_Price), 10)
#8 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Catalog/Model/Layer/Filter/Price.php(115): Mage_Catalog_Model_Layer_Filter_Price->getRangeItemCounts(10)
#9 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Catalog/Model/Layer/Filter/Price.php(314): Mage_Catalog_Model_Layer_Filter_Price->getPriceRange()
#10 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Catalog/Model/Layer/Filter/Abstract.php(151): Mage_Catalog_Model_Layer_Filter_Price->_getItemsData()
#11 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Catalog/Model/Layer/Filter/Abstract.php(120): Mage_Catalog_Model_Layer_Filter_Abstract->_initItems()
#12 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Catalog/Model/Layer/Filter/Abstract.php(109): Mage_Catalog_Model_Layer_Filter_Abstract->getItems()
#13 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Catalog/Block/Layer/Filter/Abstract.php(132): Mage_Catalog_Model_Layer_Filter_Abstract->getItemsCount()
#14 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/design/frontend/decostore/default/template/catalog/layer/view.phtml(49): Mage_Catalog_Block_Layer_Filter_Abstract->getItemsCount()
#15 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Block/Template.php(241): include('/Users/Ditchou/...')
#16 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Block/Template.php(272): Mage_Core_Block_Template->fetchView('frontend/decost...')
#17 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Block/Template.php(286): Mage_Core_Block_Template->renderView()
#18 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Block/Abstract.php(863): Mage_Core_Block_Template->_toHtml()
#19 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Block/Text/List.php(43): Mage_Core_Block_Abstract->toHtml()
#20 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Block/Abstract.php(863): Mage_Core_Block_Text_List->_toHtml()
#21 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Block/Abstract.php(582): Mage_Core_Block_Abstract->toHtml()
#22 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Block/Abstract.php(526): Mage_Core_Block_Abstract->_getChildHtml('left', true)
#23 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/design/frontend/decostore/default/template/page/2columns-left.phtml(19): Mage_Core_Block_Abstract->getChildHtml('left')
#24 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Block/Template.php(241): include('/Users/Ditchou/...')
#25 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Block/Template.php(272): Mage_Core_Block_Template->fetchView('frontend/decost...')
#26 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Block/Template.php(286): Mage_Core_Block_Template->renderView()
#27 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Block/Abstract.php(863): Mage_Core_Block_Template->_toHtml()
#28 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Model/Layout.php(555): Mage_Core_Block_Abstract->toHtml()
#29 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Controller/Varien/Action.php(390): Mage_Core_Model_Layout->getOutput()
#30 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Catalog/controllers/CategoryController.php(159): Mage_Core_Controller_Varien_Action->renderLayout()
#31 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Controller/Varien/Action.php(419): Mage_Catalog_CategoryController->viewAction()
#32 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Controller/Varien/Router/Standard.php(250): Mage_Core_Controller_Varien_Action->dispatch('view')
#33 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Controller/Varien/Front.php(176): Mage_Core_Controller_Varien_Router_Standard->match(Object(Mage_Core_Controller_Request_Http))
#34 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Model/App.php(354): Mage_Core_Controller_Varien_Front->dispatch()
#35 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/Mage.php(683): Mage_Core_Model_App->run(Array)
#36 /Users/Ditchou/Documents/ProjetsWeb/lolote/index.php(87): Mage::run('', 'store')
#37 {main}

ここでエラーが発生するようです: Object(Varien_Db_Select))

単純にやるとわからない

$collectionSimple = Mage::getResourceModel('catalog/product_collection')
     ->addAttributeToFilter('type_id', array('eq' => 'simple'));

SQLリクエストのエコーは私に与えます:

SELECT `e`.*, `cat_index`.`position` AS `cat_index_position`, `price_index`.`price`, `price_index`.`tax_class_id`, `price_index`.`final_price`, IF(price_index.tier_price IS NOT NULL, LEAST(price_index.min_price, price_index.tier_price), price_index.min_price) AS `minimal_price`, `price_index`.`min_price`, `price_index`.`max_price`, `price_index`.`tier_price` FROM `catalog_product_entity` AS `e` INNER JOIN `catalog_category_product_index` AS `cat_index` ON cat_index.product_id=e.entity_id AND cat_index.store_id=1 AND cat_index.visibility IN(2, 4) AND cat_index.category_id='3' INNER JOIN `catalog_product_index_price` AS `price_index` ON price_index.entity_id = e.entity_id AND price_index.website_id = '1' AND price_index.customer_group_id = 0 WHERE (`e`.`type_id` = 'simple')

できます。

層モデルのコレクションが異なるのはなぜですか?

4

3 に答える 3

8

それがあなたが得ているエラーだと確信していますか?Magento 1.7.x で、prepareProductCollectionメソッド本体を上記のものに置き換えると、このエラーが発生します

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'e.min_price' in 'where clause'

これprepareProductCollectionは、オリジナルと同じプロパティを設定しなかったためです。手始めに、あなたのものであることを確認してください。構成ベースの書き換えでこれを行っている場合は、呼び出します

parent::prepareProductCollection($collection);

メソッドの開始時に。localまたはコード プール オーバーライドを使用している場合はcommunity、ファイルからコードをコピーして貼り付ける必要がありcoreます。1.7.1 では、次のようになります。

    $collection
        ->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
        ->addMinimalPrice()
        ->addFinalPrice()
        ->addTaxPercents()
        ->addUrlRewrite($this->getCurrentCategory()->getId());

    Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($collection);
    Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection);

    $collection
        ->addAttributeToSelect('type_id')
        ->addAttributeToFilter('type_id','simple');

それでも問題が解決しない場合は、コールスタックをトレースしてください。エラーが本当にある場合は、コレクションのフィルターを1054 Unknown column 'e.type_id' in 'where clause'のコレクションにコピーするカスタム コードがどこかで実行されていると思います。

また、次を使用して、コレクションのプライマリ SQL クエリを取得できます。

echo $collection->getSelect()->__toString();

これで十分なデバッグ情報が得られるはずです。

更新:上記の新しい情報に基づくと、これは価格フィルターがある場合、および/またはインデックスが特定の状態にある場合にのみ発生するようです。

これがあなたの問題です。このコールスタック行を見てください

#7 app/code/core/Mage/Catalog/Model/Layer/Filter/Price.php(158):    Mage_Catalog_Model_Resource_Layer_Filter_Price->getCount(Object(Mage_Catalog_Model_Layer_Filter_Price), 10)

メソッドにジャンプするとgetCount、次の呼び出しが表示されます。_getSelect

#File: app/code/core/Mage/Catalog/Model/Resource/Layer/Filter/Price.php 
public function getCount($filter, $range)
{
    $select = $this->_getSelect($filter);

の定義を見ると_getSelect

#partial method reproduction
#File: app/code/core/Mage/Catalog/Model/Resource/Layer/Filter/Price.php
protected function _getSelect($filter)
{    
    $collection = $filter->getLayer()->getProductCollection();
    $collection->addPriceData($filter->getCustomerGroupId(), $filter->getWebsiteId());
    if (!is_null($collection->getCatalogPreparedSelect())) {
        $select = clone $collection->getCatalogPreparedSelect();
    } else {
        $select = clone $collection->getSelect();
    }

Magento がコレクションから選択を複製し、インデックス テーブルから選択するように変更していることがわかります。

    // processing FROM part
    $priceIndexJoinPart = $fromPart[Mage_Catalog_Model_Resource_Product_Collection::INDEX_TABLE_ALIAS];
    $priceIndexJoinConditions = explode('AND', $priceIndexJoinPart['joinCondition']);
    $priceIndexJoinPart['joinType'] = Zend_Db_Select::FROM;
    $priceIndexJoinPart['joinCondition'] = null;
    $fromPart[Mage_Catalog_Model_Resource_Product_Collection::MAIN_TABLE_ALIAS] = $priceIndexJoinPart;
    unset($fromPart[Mage_Catalog_Model_Resource_Product_Collection::INDEX_TABLE_ALIAS]);
    $select->setPart(Zend_Db_Select::FROM, $fromPart);
    foreach ($fromPart as $key => $fromJoinItem) {
        $fromPart[$key]['joinCondition'] = $this->_replaceTableAlias($fromJoinItem['joinCondition']);
    }
    $select->setPart(Zend_Db_Select::FROM, $fromPart);

インデックス テーブルには列がないため type_id、上記のストック Magento コードは変更と互換性がありません。もし私がこれを進めるつもりなら、私は

  1. 書き換えベースのアプローチに移行する

  2. type_idオーバーライドの代わりにフィルターを追加する書き換えを作成します

  3. _getSelectフィルターの選択をチェックし、type_idそれが見つかった場合は削除する上記のメソッドで 2 番目のリライトを作成します。

または、別の方法を見つけて、使用されている場所に近いコレクション オブジェクトを書き換えることもできます。

幸運を!

于 2012-12-01T23:33:13.480 に答える
1

レイヤー ナビゲーションをカスタム コレクション (カテゴリや検索コレクションに依存するコレクションではない) に追加しようとしたときに、2 ~ 3 週間前に同じ問題が発生しました。階層化されたナビゲーションで使用される価格フィルター処理に起因する、あなたが遭遇したのと同じ問題がありました。Alan が提案したように、Magento 1.7 では、価格フィルタリング オプションに使用される選択 SQL を最適化しました。FROM sql 部分 (製品エンティティ - type_id 属性を含む) を削除し、price_index 関連テーブルをメイン テーブル (クエリの FROM 部分で使用されるテーブル) にします。したがって、基本的に、データが選択されるテーブルは製品エンティティ テーブルではなくなります (すべての製品の基本属性が失われます)。メイン テーブルが製品インデックスになります。これは、Magento チームが 1 から追加したコア アップデートです。

また、これに対する有効な修正もあります。明日共有します。現在、コードにアクセスすることはできません。

于 2012-12-02T21:29:12.530 に答える
0

select ステートメントからエラーの原因となっているフィールドを削除したときに、サイドバーの価格フィルターの正しいセットを返さない _getSelect 関数を拡張するという問題がありました。

そのため、フィールドが存在しないという問題を回避するために、存在するフィールド、entity_id を使用しました。関数 getProductCollection を変更して、Mage_Catalog_Model_Category を拡張しました。

$collection = Mage::getResourceModel('catalog/product_collection')
    ->setStoreId($this->getStoreId())
    ->addAttributeToFilter('type_id', array('eq' => 'simple'));
// Get the product ids of the filtered collection
$entityIds = $collection->getAllIds();

$collection = Mage::getResourceModel('catalog/product_collection')
    ->setStoreId($this->getStoreId())
    ->addCategoryFilter($this)
    // Apply the product ids as a filter
    ->addIdFilter($entityIds,false);

return $collection;
于 2013-02-21T03:17:03.910 に答える