Magento Collection Фильтрующие функции - PullRequest
6 голосов
/ 24 сентября 2011

В чем разница между addAttributeToFilter () и addFieldToFilter () при работе с коллекциями Magento? Имеет ли это какое-либо отношение к тому, является ли значение eav_attribute?

РЕДАКТИРОВАТЬ: Согласно http://www.magentocommerce.com/wiki/5_-_modules_and_development/catalog/using_collections_in_magento:

addFieldToFilter ($ attribute, $ condition = null) - псевдоним для addAttributeToFilter ()

Кто-нибудь может это подтвердить?

1 Ответ

29 голосов
/ 24 сентября 2011

Извините, нет короткого ответа, который не вводил бы в заблуждение и не путал вещи здесь.

Важный момент # 1: Основная команда Magento не хочет удалять или переименовывать методы из исходного дерева.Культура стартапов означала, что они отказались от тестов, и, будучи публичным проектом, они не могли контролировать то, что люди делали со своим продуктом.Вместо того, чтобы удалять методы и рисковать, они оставят методы на месте, которые вызывают новый метод.Таким образом, даже если есть старый код, который вызывает метод, они покрыты.

Важный момент №2. Цепочка наследования коллекций является неуклюжей и непоследовательно применялась в некоторых частях кодовой базы.Это очищается, но все равно может легко привести вас к петле.

Важный момент # 3: я размышляю над тем, как многое из этого должно быть использовано и произошло.Я не окончательный авторитет здесь, я просто кто-то пытается понять это.Приведенные ниже сведения относятся к 1.6, но эти понятия применимы ко всем версиям

Все коллекции наследуются от класса Varien_Data_Collection_Db.Это класс, который моделирует базовую концепцию «сбора серии объектов, загруженных из базы данных».Этот класс имеет единственный метод addFieldToFilter.

public function addFieldToFilter($field, $condition=null)
{
    $field = $this->_getMappedField($field);
    $this->_select->where($this->_getConditionSql($field, $condition), null, Varien_Db_Select::TYPE_CONDITION);
    return $this;
}

, который представляет собой простую реализацию, которая добавляет предложение where к теоретическому запросу.

Далее, есть два абстрактных класса, которые имеют Varien_Data_Collection_Db в качестве предка.Mage_Core_Model_Resource_Db_Collection_Abstract и Mage_Eav_Model_Entity_Collection_Abstract.

Mage_Core_Model_Resource_Db_Collection_Abstract - это класс коллекции для "обычных, не EAV моделей".Он не имеет ни метода addFieldToFilter, ни метода addAttributeToFilter.Он основан на реализации базового класса Varien_Data_Collection_Db.

Mage_Eav_Model_Entity_Collection_Abstract - это класс коллекции для моделей EAV.У него есть метод addAttributeToFilter, который является более сложным.

public function addAttributeToFilter($attribute, $condition = null, $joinType = 'inner')
{
    if ($attribute === null) {
        $this->getSelect();
        return $this;
    }

    if (is_numeric($attribute)) {
        $attribute = $this->getEntity()->getAttribute($attribute)->getAttributeCode();
    } else if ($attribute instanceof Mage_Eav_Model_Entity_Attribute_Interface) {
        $attribute = $attribute->getAttributeCode();
    }

    if (is_array($attribute)) {
        $sqlArr = array();
        foreach ($attribute as $condition) {
            $sqlArr[] = $this->_getAttributeConditionSql($condition['attribute'], $condition, $joinType);
        }
        $conditionSql = '('.implode(') OR (', $sqlArr).')';
    } else if (is_string($attribute)) {
        if ($condition === null) {
            $condition = '';
        }
        $conditionSql = $this->_getAttributeConditionSql($attribute, $condition, $joinType);
    }

    if (!empty($conditionSql)) {
        $this->getSelect()->where($conditionSql, null, Varien_Db_Select::TYPE_CONDITION);
    } else {
        Mage::throwException('Invalid attribute identifier for filter ('.get_class($attribute).')');
    }

    return $this;
}

Это потому, что запрос атрибута не прямой запрос "где".Кроме того, этот метод был разработан для получения либо имени атрибута, или идентификатора базы данных атрибутов, или экземпляра объекта атрибута.Вы не добавляете поле в фильтр, вы добавляете атрибут в фильтр.Таким образом, в зависимости от реализации EAV и таблицы, в которой хранится атрибут, вам необходимо добавить другой бит кода SQL (прямой запрос «где» в основной таблице, «где» добавляется с помощью одной из таблиц объединения и т. Д.)

Это создает проблему.Поскольку этот объект коллекции EAV наследуется от базового объекта коллекции, addFieldToFilter все еще существует и все равно добавит базовое условие where в запрос EAV, что может привести в замешательство конечного пользователя, не выполнив то, что он думал.Следовательно, класс коллекции EAV также имеет этот

public function addFieldToFilter($attribute, $condition = null)
{
    return $this->addAttributeToFilter($attribute, $condition);
}

, который переносит любой вызов от addFieldToFilter до addAttributeToFilter (опять же, в модели EAV).Итак, если у вас есть модель EAV, вы можете использовать addFieldToFilter или addAttributeToFilter.Если вы работаете с обычной моделью, вы можете только звонить addFieldToFilter, addAttributeToFilter не существует.

В идеале имена методов должны были бы быть унифицированы с самого начала, но как только произошло разделение, команда Magento решила продолжить поддерживать разделение в пользу обратной совместимости.

Подождите, есть еще

В базе кода осталось две коллекции, которые наследуют напрямую от Varien_Data_Collection_Db.Это Mage_Sales_Model_Resource_Sale_Collection и Mage_Review_Model_Resource_Review_Summary_Collection.Это число выше в версиях Magento CE до 1.6.Хотя это не влияет на вопрос фильтрации, оно запутывает цепочку наследования, поэтому вам следует остерегаться этого.

Многие не-EAV коллекции будут реализовывать свои собственные addFieldToFilter для проверки работоспособности переменных или небольшого колебания параметров запроса, если они делают что-то немного нестандартное.

Коллекции EAV также включаются в это действие, переопределяя addAttributeToFilter.Опять же, это сделано для добавления пользовательской логики, которая не вписывается в базовую загрузку коллекции Magento.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...