Magento JoinLeft() в сетке пользовательских заказов, вызывающей нарушение ограничения целостности SQL для пользователя без прав администратора при настройке нескольких веб-сайтов
Я продлил Mage_Adminhtml_Block_Sales_Order_Grid
класс с пользовательским модулем для добавления нескольких атрибутов клиента (Magento EE 1.10) в сетку.
Я добавил пользовательские атрибуты в коллекцию в моем MyCompany_MyModule_Block_Adminhtml_Order_Grid
класс в _prepareCollection()
метод с использованием трех соединений, как это:
protected function _prepareCollection()
{
$collection = Mage::getResourceModel($this->_getCollectionClass());
//get the table names for the customer attributes we'll need
$customerEntityVarchar = Mage::getSingleton('core/resource')
->getTableName('customer_entity_varchar');
$customerEntityInt = Mage::getSingleton('core/resource')
->getTableName('customer_entity_int');
// add left joins to display the necessary customer attribute values
$collection->getSelect()->joinLeft(array(
'customer_entity_int_table'=>$customerEntityInt),
'`main_table`.`customer_id`=`customer_entity_int_table`.`entity_id`
AND `customer_entity_int_table`.`attribute_id`=148',
array('bureau'=>'value'));
$collection->getSelect()->joinLeft(array(
'customer_entity_varchar_table'=>$customerEntityVarchar),
'`main_table`.`customer_id`=`customer_entity_varchar_table`.`entity_id`
AND `customer_entity_varchar_table`.`attribute_id`=149',
array('index_code'=>'value'));
$collection->getSelect()->joinLeft(array(
'customer_entity_varchar_2_table'=>$customerEntityVarchar),
'`main_table`.`customer_id`=`customer_entity_varchar_2_table`.`entity_id`
AND `customer_entity_varchar_2_table`.`attribute_id`=150',
array('did_number'=>'value'));
$this->setCollection($collection);
return parent::_prepareCollection();
}
ОБНОВЛЕНИЕ: Хотя все отображается нормально при просмотре заказов, все не так хорошо, когда я пытаюсь найти / отфильтровать заказы по любому из полей объединения текста (index_code
или же did_number
). Результатом является ошибка SQL: "SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'store_id' in where clause is ambiguous
".
Эта проблема также существует, если я удаляю все, кроме одного из leftJoin()
заявления, поэтому что-то не так с обоими (любым) из объединений с customer_entity_varchar
Таблица.
4 ответа
Поскольку сейчас есть два столбца с именем store_id, вы должны указать filter_index
когда вы добавляете столбец в сетку:
$this->addColumn('store_id', array(
...
'filter_index'=>'main_table.store_id',
));
Чтобы он знал, на кого вы ссылаетесь при фильтрации.
Я надеюсь, что это помогает!
Скорее всего, это потому, что вы присоединяетесь customer_entity_varchar_table
дважды.
$collection->getSelect()->joinLeft(array(
'customer_entity_varchar_table'=>$customerEntityVarchar),
'`main_table`.`customer_id`=`customer_entity_varchar_table`.`entity_id`
AND `customer_entity_varchar_table`.`attribute_id`=149',
array('index_code'=>'value'));
$collection->getSelect()->joinLeft(array(
'customer_entity_varchar_2_table'=>$customerEntityVarchar),
'`main_table`.`customer_id`=`customer_entity_varchar_2_table`.`entity_id`
AND `customer_entity_varchar_2_table`.`attribute_id`=150',
array('did_number'=>'value'));
Вы можете объединить их, вы также можете попробовать распечатать SQL-код, чтобы увидеть, как выглядит запрос:
$collection->getSelect()->getSelectSql();
Больше информации о коллекциях: http://blog.chapagain.com.np/magento-collection-functions/
Проблема существует в двух разных местах. Один случай, если вы вошли в систему как пользователь с одним хранилищем, другой - как пользователь, который может фильтровать различные хранилища.
Один пользователь магазина
Решение, с которым я пошел, было переопределить addAttributeToFilter
метод в классе коллекции. Не зная точно, что меняет Enterprise_AdminGws_Model_Collections::addStoreAttributeToFilter
Метод будет влиять на другое поведение, я хотел бы избежать этого, и я нашел добавление индекса фильтра в Mage_Adminhtml_Block_Sales_Order_Grid
как предположил Хавьер, не сработало.
Вместо этого я добавил следующий метод Mage_Sales_Model_Resource_Order_Grid_Collection
:
/**
* {@inheritdoc}
*/
public function addAttributeToFilter($attribute, $condition = null)
{
if (is_string($attribute) && 'store_id' == $attribute) {
$attribute = 'main_table.' . $attribute;
}
return parent::addFieldToFilter($attribute, $condition);
}
Патч можно найти здесь: https://gist.github.com/josephdpurcell/baf93992ff2d941d02c946aeccd48853
Мульти-магазин пользователя
Если пользователь может фильтровать заказы по хранилищу в admin/sales_order, необходимо также внести следующие изменения в Mage_Adminhtml_Block_Sales_Order_Grid в строке 75:
if (!Mage::app()->isSingleStoreMode()) {
$this->addColumn('store_id', array(
'header' => Mage::helper('sales')->__('Purchased From (Store)'),
'index' => 'store_id',
'type' => 'store',
'store_view'=> true,
'display_deleted' => true,
'filter_index' => 'main_table.store_id',
));
}
Патч можно найти здесь: https://gist.github.com/josephdpurcell/c96286a7c4d2f5d1fe92fb36ee5d0d5a
У меня была та же ошибка, после поиска кода, я наконец нашел нарушителя, который находится в Enterprise_AdminGws_Model_Collections
класс в строке ~235:
/**
* Add store_id attribute to filter of EAV-collection
*
* @param Mage_Eav_Model_Entity_Collection_Abstract $collection
*/
public function addStoreAttributeToFilter($collection)
{
$collection->addAttributeToFilter('store_id', array('in' => $this->_role->getStoreIds()));
}
Вы должны заменить 'store_id'
от 'main_table.store_id'
Конечно, вам придется расширить этот конкретный метод в своем собственном переписывании, чтобы придерживаться рекомендаций Magento:p
Надеюсь, поможет!