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

Надеюсь, поможет!

Другие вопросы по тегам