Magento - mô hình tùy chỉnh (không phải eav), tải theo nhiều trường


15

Tôi có một mô hình tùy chỉnh và mô hình tài nguyên. Tôi muốn tải một phiên bản duy nhất của mô hình bằng cách sử dụng nhiều hơn 1 trường.

Mô hình có các trường sau:

id
tag_name
custom_name
group_name

Tôi muốn tải mô hình này dựa trên tag_name, custom_name và group_name thay vì id.

Hiện tại tôi đang sử dụng một bộ sưu tập và addFilter cho từng lĩnh vực. Điều này hoạt động, nhưng tôi tự hỏi nếu có một chiến lược tiêu chuẩn cho loại điều này trong Magento?

BIÊN TẬP

Core magento dường như không sử dụng các bộ sưu tập cho kịch bản này mà thay vào đó, nó sử dụng các truy vấn sql trực tiếp trong các mô hình tài nguyên.

một ví dụ về điều này là:

loadByAccountAndDate() trong Mage_Paypal_Model_Resource_Report_Settlement

Có một lý do cho điều này, khi các bộ sưu tập dường như là một cách ngắn gọn hơn, về số lượng mã được viết

Tôi chỉ không biết tại sao magento chọn làm theo cách này

Câu trả lời:


21

Tôi nghĩ rằng đây là một cách tiếp cận tốt. Có lẽ bạn cần tạo một trình bao bọc trong lớp mô hình để bạn sẽ tránh viết đi viết lại nhiều lần.
Cái gì đó như:

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

Và bạn có thể tải vật phẩm như thế này ở bất kỳ nơi nào khác:

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

Tôi đã cập nhật câu hỏi của mình với những lo ngại về việc sử dụng các bộ sưu tập
Marty Wallace

Nếu bạn thực sự muốn loại trừ các bộ sưu tập khỏi logic của mình, hãy kiểm tra xem @mageUz đã viết gì trong câu trả lời của anh ấy. Tôi đã không kiểm tra nó, nhưng các đường nối giống như một ý tưởng tốt. Lưu ý: Tôi vẫn không thấy bất kỳ vấn đề nào trong việc sử dụng các bộ sưu tập.
Marius

Không phải là tôi muốn loại trừ chúng, nhưng tôi muốn sử dụng các thực hành tốt nhất của magento. Nếu mã lõi đang làm một cái gì đó theo một cách cụ thể thì thông thường đó sẽ là dấu hiệu của một cái gì đó để làm theo. Nhưng tôi đang hỏi trên diễn đàn này về sự xác định vì trong trường hợp này tôi thực sự không biết cách tốt nhất
Marty Wallace

1
Tôi cũng có mối quan tâm sử dụng các bộ sưu tập trong trường hợp này. Có lẽ bộ sưu tập trong câu hỏi có một _itemObjectClasscái giống như mô hình thực sự gọi loadByMultiple. Vì vậy, kết quả là, sẽ không phải $x = Mage::getModel('some/model')là một thể hiện của một mô hình và $x->loadByMultiple($tag, $customName, $group)thực sự là một thể hiện khác / mới?
kojiro

@kojiro. Vâng, nó sẽ là một ví dụ khác nhau nhưng cũng vậy loadByAttribute. Xem câu hỏi này để tham khảo: magento.stackexchange.com/q/5926/146
Marius

7

Mô-đun / Mô hình / Một sốModel.php

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

Mô-đun / Mô hình / Tài nguyên / Một sốModel.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);
    }

Và cuối cùng bạn có thể tải mô hình sau:

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

Đã cập nhật

Bằng cách này, bạn có thể sử dụng phương thức này (loadByAttribut) một cách dễ dàng hơn là bộ sưu tập và nó dễ hiểu hơn. Magento cũng gửi một số sự kiện trong khi tải bộ sưu tập hoặc thực thể và tiện ích mở rộng của bên thứ ba có thể cập nhật bộ sưu tập hoặc thực thể bởi người quan sát. Nếu bạn tải thực thể thông qua tài nguyên (ví dụ như của tôi và của bạn), không có sự kiện / người quan sát nào kích hoạt và bạn có thể nhận được thực thể "sạch" nhanh hơn thay vì thu thập. Ngoài ra Magento không sử dụng bộ sưu tập được lưu trong bộ nhớ cache bằng cách này, nó tải nó trực tiếp từ bảng db.
Có lẽ đó là lý do của việc sử dụng phương pháp này bởi các mô-đun lõi Magento.


Tôi nghĩ rằng bạn đang thiếu một getData () trên dòng này : $this->setData($this->getResource()->loadByAttributes($attributes));, phải là: $this->setData($this->getResource()->loadByAttributes($attributes)->getData()); Phải không?
Mihai MATEI

2

Bạn đang làm điều đó đúng với addFilter. Trong Magento bạn có thể tải theo bất kỳ thuộc tính nào nhưng không phải nhiều thuộc tính cùng một lúc. Bằng cách thêm các bộ lọc, bạn đạt được hiệu ứng tương tự mà không cần thêm chi phí.


Sử dụng db select sẽ không tốt hơn sử dụng bộ sưu tập?
Marty Wallace

Bạn nghĩ addFiltergì đang làm? :-)
user487772

Bạn có thể xem loadByAccountAndDate () trong Mage_Paypal_Model_Resource_Report_Scharge vì đây là sử dụng một lựa chọn thay vì bộ sưu tập
Marty Wallace

Và thực sự tình huống này trong mã lõi hầu như chỉ như thế này và tôi không thể thấy bất kỳ bộ sưu tập nào sử dụng
Marty Wallace

1
Tôi đã cập nhật câu hỏi của mình với những lo ngại về việc sử dụng các bộ sưu tập
Marty Wallace

1

Thứ nhất - chiến lược của bạn để lọc một bộ sưu tập là chính xác. Vì các bộ sưu tập trong Magento tải nhanh, bạn có khả năng tạo các phương thức trong mô hình tài nguyên của mình để xác định chặt chẽ hơn các yêu cầu của tải tùy chỉnh của bạn.

Nếu không có một số mã của bạn để lấy mẫu, hãy xem xét phương thức giả sau đây trong Mô hình tài nguyên của bạn:

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

    }
}

Tôi đã cập nhật câu hỏi của mình với những lo ngại về việc sử dụng các bộ sưu tập cho trường hợp sử dụng cụ thể này nhưng tôi không có đủ kiến ​​thức để biết tại sao magento lại làm theo cách này
Marty Wallace
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.