Magento - нестандартна модель, що завантажується декількома полями


15

У мене є власна модель та модель ресурсів. Я хочу завантажити один екземпляр моделі, використовуючи більше 1 поля.

Модель має такі поля:

id
tag_name
custom_name
group_name

Я хочу завантажити цю модель на основі тегів_мення, власного_імені та імені групи замість ідентифікатора.

В даний час я використовую колекцію та addFilter для кожного поля. Це працює, але мені було цікаво, чи існує стандартна стратегія такого типу речей у Magento?

EDIT

Core magento, схоже, не використовує колекції для цього сценарію, але натомість використовує прямі запити sql у моделях ресурсів.

Приклад цього:

loadByAccountAndDate() в Mage_Paypal_Model_Resource_Report_Settlement

Чи є причина цього, коли збірники здаються більш стислим способом з точки зору кількості написаного коду

Я просто не знаю, чому Магенто вирішує зробити це саме так

Відповіді:


22

Я думаю, що це хороший підхід. Можливо, вам потрібно створити обгортку в модельному класі, щоб ви уникали писати одне і те ж і знову.
Щось на зразок:

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
}

Я оновив своє запитання щодо своїх проблем щодо використання колекцій
Marty Wallace

Якщо ви дійсно хочете виключити колекції зі своєї логіки, перевірте, що @mageUz написав у своїй відповіді. Я не перевіряв цього, але шви - це гарна ідея. Примітка. Я все ще не бачу проблем із використанням колекцій.
Маріус

Це не те, що я хотів би їх виключити, але я хочу використовувати найкращі практики магенто. Якщо основний код робить щось певним чином, то, як правило, це має бути ознакою чогось слідувати. Але я прошу на цьому форумі впевненості, що в цьому випадку я справді не знаю найкращого способу
Марті Уоллес

1
У мене також є проблеми щодо використання колекцій у цьому випадку. Імовірно, що колекція, про _itemObjectClassяку йдеться, має таку саму модель, яка насправді викликає loadByMultiple. Отже, не був $x = Mage::getModel('some/model')би один екземпляр моделі, а $x->loadByMultiple($tag, $customName, $group)насправді був би іншим / новим екземпляром?
kojiro

@kojiro. Так, це буде інший екземпляр, але так і є loadByAttribute. Дивіться це запитання для довідки: magento.stackexchange.com/q/5926/146
Marius

7

Модуль / Модель / SomeModel.php

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

Модуль / Модель / Ресурс / 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 також розсилає деякі події, в той час як завантаження колекції чи розширення сутності та сторонніх розробників може оновлювати колекцію чи сутність спостерігачем. Якщо ви завантажуєте сутність за допомогою ресурсу (наведеного в прикладі мого і вашого), жодна подія / спостерігачі не стріляють, і ви можете отримати "чисте" об'єкт швидше, ніж збір. Також Magento не використовує кешований збір таким чином, він завантажує його безпосередньо з db-таблиці.
Можливо, це причина використання цього методу основними модулями Magento.


Я думаю, вам не вистачає getData () у цьому рядку:, $this->setData($this->getResource()->loadByAttributes($attributes));що має бути: $this->setData($this->getResource()->loadByAttributes($attributes)->getData()); Так?
Mihai MATEI

2

Ви робите це правильно addFilter. У Magento ви можете завантажити будь-який атрибут, але не кілька атрибутів одночасно. Додаючи фільтри, ви досягаєте такого ж ефекту без зайвих накладних витрат.


Використання db select не було б краще, ніж використання колекції?
Марті Уоллес

Як ви думаєте addFilter, що робить? :-)
user487772

Ви можете подивитися loadByAccountAndDate () в Mage_Paypal_Model_Resource_Report_Settlement, оскільки для цього використовується вибір, а не колекція
Марті Уоллес

І насправді ця ситуація в основному коді майже виключно така, і я не можу побачити жодної з колекцій
Marty Wallace

1
Я оновив своє запитання щодо своїх проблем щодо використання колекцій
Marty Wallace

1

По-перше - ваша стратегія фільтрації колекції є правильною. Оскільки колекції в Magento lazy-load ви маєте можливість створювати методи у вашій моделі ресурсів, щоб більш чітко визначити вимоги вашого власного навантаження.

Не маючи свого коду для вибірки, врахуйте наступний псевдо-метод у вашій моделі ресурсів:

<?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;

    }
}

Я оновив своє запитання щодо своїх проблем щодо використання колекцій для цього конкретного випадку використання, але я не маю достатньо знань, щоб знати, чому magento робить це саме так
Марті Уоллес
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.