Magento Ajax购物车添加商品报错:salesrule表无website_ids列
解决Magento Ajax Cart添加商品时的
website_ids列不存在错误 嘿,我看你在自定义Magento主题的Ajax Cart系统时碰到了这个棘手的SQL错误,我来帮你拆解下问题和解决方案:
错误信息
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'website_ids' in 'where clause'
你的代码
function add_to_cartAction($product = false) { $data = json_decode(base64_decode($_POST['data']) , true); if(!$product) { $product = Mage::getModel('catalog/product')->load($data['entity_id']); } try{ if($product->getTypeId() == 'simple'){ $params = array( 'qty' => $data['quantity'] , 'product' => $product->getId() ); $this->addProduct($product , $params); die(base64_encode(json_encode(array('success' => 'Successfully added product to cart')))); }else{ $options = $data['attrs']; $_matchedItem = null; $childProducts = Mage::getModel('catalog/product_type_configurable')->getUsedProducts(null,$product); foreach($childProducts as $item) { $matchAmount = count($options); $matched = 0; foreach($options as $attr => $option) { if($item->getData($attr) == $option) { $matched++; } } if($matched == $matchAmount) { $_matchedItem = $item; break; } } if($_matchedItem == null) { throw new Exception("Matched Item is null"); } $params = array( 'qty' => $data['quantity'] , 'product' => $_matchedItem->getId() ); $this->addProduct($_matchedItem , $params); die(base64_encode(json_encode(array('success' => 'Successfully added product to cart')))); } }catch(Exception $e) { die($e->getMessage()); } } function addProduct($product , $params) { $cart = Mage::getModel('checkout/cart'); $cart->init(); $cart->setWebsiteId(Mage::app()->getWebsite()->getId()); $cart->setStoreId(Mage::app()->getStore()->getId()); $cart->getQuote()->addProduct($product , $params['qty']); $cart->getQuote()->save(); $cart->save(); }
问题分析
你提到正常运行的Magento实例里salesrule表同样没有website_ids列却能正常工作,这说明问题不在数据库结构,而是你的代码对购物车实例的处理有误:
- 错误使用购物车实例:你用
Mage::getModel('checkout/cart')创建新的购物车实例,而Magento的购物车是单例模式,应该用Mage::getSingleton('checkout/cart')来获取用户当前会话的购物车,否则会创建孤立的购物车实例,触发异常的查询逻辑。 - 重复设置网站/商店ID:
$cart->init()方法已经自动根据当前会话初始化了对应的网站和商店ID,之后手动调用setWebsiteId和setStoreId会导致quote对象的上下文混乱,触发salesrule模块的错误查询(某些Magento版本的促销规则逻辑在上下文异常时会错误引用不存在的website_ids列)。 addProduct参数错误:$cart->getQuote()->addProduct()方法的第二个参数应该是包含qty等信息的数组,而你传的是单纯的数值$params['qty'],这会导致方法内部参数解析异常,间接引发后续的SQL错误。
修正后的代码
function add_to_cartAction($product = false) { $data = json_decode(base64_decode($_POST['data']) , true); if(!$product) { $product = Mage::getModel('catalog/product')->load($data['entity_id']); } try{ if($product->getTypeId() == 'simple'){ $params = array( 'qty' => $data['quantity'] , 'product' => $product->getId() ); $this->addProduct($product , $params); die(base64_encode(json_encode(array('success' => 'Successfully added product to cart')))); }else{ $options = $data['attrs']; $_matchedItem = null; $childProducts = Mage::getModel('catalog/product_type_configurable')->getUsedProducts(null,$product); foreach($childProducts as $item) { $matchAmount = count($options); $matched = 0; foreach($options as $attr => $option) { if($item->getData($attr) == $option) { $matched++; } } if($matched == $matchAmount) { $_matchedItem = $item; break; } } if($_matchedItem == null) { throw new Exception("Matched Item is null"); } $params = array( 'qty' => $data['quantity'] , 'product' => $_matchedItem->getId() ); $this->addProduct($_matchedItem , $params); die(base64_encode(json_encode(array('success' => 'Successfully added product to cart')))); } }catch(Exception $e) { die($e->getMessage()); } } function addProduct($product , $params) { // 使用单例获取当前会话的购物车 $cart = Mage::getSingleton('checkout/cart'); $cart->init(); // 修正addProduct的参数,传入完整的params数组 $cart->getQuote()->addProduct($product , $params); $cart->getQuote()->save(); // 触发购物车的更新逻辑,确保会话同步 $cart->save(); Mage::getSingleton('checkout/session')->setCartWasUpdated(true); }
额外说明
添加Mage::getSingleton('checkout/session')->setCartWasUpdated(true)是为了确保购物车的更新状态同步到用户会话,避免前端购物车计数不刷新的问题;如果你使用的是Magento 1.9及以上版本,建议在处理Ajax请求时确保会话正确初始化,避免出现会话丢失的问题。
内容的提问来源于stack exchange,提问作者Hudson
相关产品推荐
相关产品推荐

