Magento - Custom (не EAV) модель, загрузка несколькими полями

magento.stackexchange https://magento.stackexchange.com/questions/4683

  •  16-10-2019
  •  | 
  •  

Вопрос

У меня есть пользовательская модель и модель ресурсов. Я хочу загрузить один экземпляр модели, используя более 1 поле.

Модель имеет следующие поля:

id
tag_name
custom_name
group_name

Я хочу загрузить эту модель на основе tag_name, custom_name и group_name вместо id.

В настоящее время я использую коллекцию и AddFilter для каждого поля. Это работает, но я задавался вопросом, есть ли стандартная стратегия для такого типа вещей в Magento?

РЕДАКТИРОВАТЬ

Core Magento, кажется, не использует коллекции для этого сценария, а вместо этого использует прямые запросы SQL в моделях ресурсов.

Примером этого является:

loadByAccountAndDate() в Mage_Paypal_Model_Resource_Report_Settlement

Есть ли причина для этого, когда коллекции кажутся более кратким способом, с точки зрения количества кода, который будет написан

Я просто не знаю, почему Magento решает сделать это таким образом

Это было полезно?

Решение

Я думаю, что это хороший подход. Может быть, вам нужно создать обертку в классе моделей, чтобы вы не написали одно и то же снова и снова.
Что-то типа:

public function loadByMultiple($tag, $customName, $group){
    $collection = $this->getCollection()
            ->addFieldToFilter('tag_name', $tag)
            ->addFieldToFilter('custom_name', $customName)
            ->addFieldToFilter('group_name', $group);
    return $collection->getFirstItem();
}

И вы можете загрузить этот элемент в любом другом месте:

$model = Mage::getModel('model/class_here')->loadByMultiple($tag, $customName, $group);
if ($model->getId()){
   //the instance exists
}
else{
    //not found
}

Другие советы

Модуль/модель/somemodel.php

public function loadByAttributes($attributes)
{
    $this->setData($this->getResource()->loadByAttributes($attributes));
    return $this;
}

Module/model/resource/somemodel.php:

public function loadByAttributes($attributes)
    {
        $adapter = $this->_getReadAdapter();
        $where   = array();
        foreach ($attributes as $attributeCode=> $value) {
            $where[] = sprintf('%s=:%s', $attributeCode, $attributeCode);
        }
        $select = $adapter->select()
            ->from($this->getMainTable())
            ->where(implode(' AND ', $where));

        $binds = $attributes;

        return $adapter->fetchRow($select, $binds);
    }

И, наконец, вы можете загрузить модель следующей:

$attributes = array('tag_name'=> 'any', 'custome_name'=> 'some','group_name'=>'some');
$model      = Mage::getModel('module/somemodel')->loadByAttributes($attributes);

Обновлено

Кстати, вы можете легко использовать этот метод (LoadByAttributes), а не сбор, и это более понятно. Magento также отправляет некоторые события, в то время как загрузка сбора или организации и третьей стороны может обновить сбор или объект обновления Observer. Если вы загружаете сущность через ресурс (приведенный в примере моего и вашего). Никакие события/наблюдатели не стреляют, и вы можете получить «чистую» сущность быстрее, а не сборы. Также Magento не использует кэшированную коллекцию таким образом, он загружает ее непосредственно из таблицы DB.
Может быть, это причина использования этого метода с помощью модулей Magento Core.

Вы делаете это правильно с addFilter. Анкет В Magento вы можете загрузить любым атрибутом, но не несколько атрибутов одновременно. Добавляя фильтры, вы достигаете того же эффекта без дополнительных накладных расходов.

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

Без некоторого вашего кода к примеру рассмотрите следующий псевдометод в модели ресурса:

<?php


class Marty_Wallace_Model_Resource_Method extends Mage_Core_Model_Resource_Db_Abstract{

    protected function _construct()
    {
        $this->_init('yourmodel/table', 'entity_id');
    }

    public function loadByCriteria(array $filter)
    {

        //$filter should be array('columnname'=>'value','columname'=>'value')

        $collection = Mage::getModel('yourmodel/class')->getCollection();

        foreach($filter as $column=>$value){
            $collection->addFieldToFilter($column,$value);
        }

        return $collection;

    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с magento.stackexchange
scroll top