我有一个自定义模型和资源模型。我想使用超过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;
}

模块/型号/资源/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 Core模块使用此方法的原因。

你正在做正确的 addFilter. 。在Magento中,您可以通过任何属性加载,但不能一次加载多个属性。通过添加过滤器,您可以达到相同的效果,而没有额外的开销。

首先 - 您过滤集合的策略是正确的。因为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;

    }
}
许可以下: CC-BY-SA归因
scroll top