简体   繁体   中英

Assign category_ids to Product by using updateAttributes in Magento

I'm trying to set category_ids to a product by using following code:

<?php
Mage::getSingleton('catalog/product_action')->updateAttributes(
    array($product->getId()), 
    array("category_ids"=>$this->convertCategories($prod['categories']))
    ,0
);
?> 

Unfortunatly script exits with an exception: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'attribute_id' in 'where clause'

Some hints? I don't want to use $product->setCategoryIds()->save() since it's much more longer in execution.

Thanks in advance.

In the end I've had to slightly modify one of magento function and make a workaround:

/**
* Updates product categories
*
* @param Mage_Catalog_Model_Product $product
* @param array $categoryIds
* @return MagentoImporter
*/
protected function updateCategories(&$product, $categoryIds)
{
    /** @var Varien_Db_Adapter_Pdo_Mysql **/
    $dbw = Mage::getSingleton('core/resource')->getConnection('core_write');
    $productCategoryTable = Mage::getSingleton('core/resource')->getTableName('catalog/category_product');

    $oldCategoryIds = $product->getCategoryIds();

    $insert = array_diff($categoryIds, $oldCategoryIds);
    $delete = array_diff($oldCategoryIds, $categoryIds);

    if (!empty($insert)) {
        $data = array();
        foreach ($insert as $categoryId) {
            if (empty($categoryId)) {
                continue;
            }
            $data[] = array(
                'category_id' => (int)$categoryId,
                'product_id'  => (int)$product->getId(),
                'position'    => 1
            );
        }
        if ($data) {
            $ris = $dbw->insertMultiple($productCategoryTable, $data);
        }
    }
    if (!empty($delete)) {
        foreach ($delete as $categoryId) {
            $where = array(
                'product_id = ?'  => (int)$product->getId(),
                'category_id = ?' => (int)$categoryId,
            );
            $ris = $dbw->delete($productCategoryTable, $where);
        }
    }
    return $this;
}

Thanks bixi for pointing out fact about category_ids, the strange thing is that although it's not an attribute there is an entry in eav_attribute table called category_ids, and magento is loading attribute model with this code, but crashing when trying to save attribute. Maybe it would be better to remove category_ids attribute at all, so people wouldn't think that its' a bug.

About indexes: probably I will need to reindex all data, just in case after using my function, it's not a big deal since product saving by using updateAttributes went from 9sec to 0.75.

You can't use updateAttributes() when dealing with categories (a category isn't an attribute). You'll have to deal with the models (catalog/product) ...

It's slow because of the indexes generation (if your indexes are on "Update On Saves") and depending of your catalog configuration (are your categories all "is_anchor" == true ?) All that is slow but needed ..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM