Thực hành tốt nhất để tham gia các thuộc tính sản phẩm


11

Tôi có một bảng tùy chỉnh với một tài liệu tham khảo sản phẩm product_id. Bây giờ tôi muốn hiển thị thông tin sản phẩm (sku, tên) trong lưới phụ trợ của mình , nhưng tôi không chắc cách thực hành tốt nhất để làm điều này là gì?

Dự đoán tốt nhất của tôi SKUlà như sau:

$collection->join(
    'catalog/product',
    'product_id=`catalog/product`.entity_id',
    array('product_sku' => 'sku')
)

(mã từ _prepareCollection() phương thức trong lớp khối lưới của tôi)

Nhưng còn tên sản phẩm thì sao? Nó có thể được tìm thấy trong catalog_product_entity_varchar. Sự hiểu biết của tôi là bạn có thể dễ dàng có được nó nếu mô hình và bộ sưu tập tài nguyên của riêng bạn dựa trên Mage_Eav_Model_Entity_Collection_Abstractvì sau đó bạn có thể sử dụng các phương thức như thế nào joinAttribute. Nhưng mô hình của tôi dựa trên một bảng đơn giản và mở rộng từ Mage_Core_Model_Resource_Db_Collection_Abstractvà không có joinAttributephương pháp nào khả dụng.

Vì vậy, cách tốt nhất để có được tên sản phẩm trong trường hợp này là gì?

Xin cám ơn về thời gian và sự giúp đỡ của bạn :-)

Cập nhật: Để chính xác hơn, tôi đã nói về mô hình và bộ sưu tập tài nguyên của tôi. Nó phù hợp với một bảng phẳng đơn giản chỉ với một vài thuộc tính như

entity_id    product_id    created_at    user_id

Ý định của tôi là tạo lưới trong phần phụ trợ, nơi tôi hiển thị một số thống kê:

ProductSku    Count(ProductSku)    MAX(created_at)

Theo tôi biết, sự chấp thuận tốt nhất để làm điều này, là thông qua lớp khối lưới và phương pháp để đi là _prepareCollection().

Phương pháp của tôi trông như thế này:

protected function _prepareCollection()
{
    // Get and set our collection for the grid
    $collection = Mage::getResourceModel($this->_getCollectionClass());
    $collection
        ->join(
            'catalog/product',
            'product_id=`catalog/product`.entity_id',
            array('product_sku' => 'sku')
            )
        ->addExpressionFieldToSelect('product_count', 'COUNT({{product_id}})', 'product_id')
        ->addExpressionFieldToSelect('newest', 'MAX({{created_at}})', array('created_at'=>'main_table.created_at'))
        ->getSelect()->group('product_id');
    $this->setCollection($collection);

    return parent::_prepareCollection();
}

Điều này hoạt động tốt cho sku (mà tôi gọi là sản phẩm_sku trong _prepareColums()phương thức. Nhưng jointôi cần chèn gì ở đây để có được tên (và ví dụ: nhà sản xuất)?

Tôi có làm gì sai không vì tôi không thể sử dụng joinLeft()?

Câu trả lời:


13

Trong lớp bộ sưu tập của bạn ( /Some/Module/Model/Mysql4 (or Resource)/YourModel/Collection.php) thêm phương thức này:

public function addProductData()
    {
        /** add particular attribute code to this array */
        $productAttributes = array('name', 'price', 'url_key');
        foreach ($productAttributes as $attributeCode) {
            $alias     = $attributeCode . '_table';
            $attribute = Mage::getSingleton('eav/config')
                ->getAttribute(Mage_Catalog_Model_Product::ENTITY, $attributeCode);

            /** Adding eav attribute value */
            $this->getSelect()->join(
                array($alias => $attribute->getBackendTable()),
                "main_table.product_id = $alias.entity_id AND $alias.attribute_id={$attribute->getId()}",
                array($attributeCode => 'value')
            );
            $this->_map['fields'][$attributeCode] = 'value';
        }
        /** adding catalog_product_entity table fields */
        $this->join(
            'catalog/product',
            'product_id=`catalog/product`.entity_id',
            array('sku' => 'sku', 'type_id' => 'type_id')
        );
        $this->_map['fields']['sku']     = 'sku';
        $this->_map['fields']['type_id'] = 'type_id';
        return $this;
    }

Trong khối lưới của bạn sử dụng chức năng này:

 protected function _prepareCollection()
    {
        $collection = Mage::getModel('some/yourmodel')
            ->getCollection()->addProductData();
        $this->setCollection($collection);
        return parent::_prepareCollection();
    }

Điều này có vẻ đầy hứa hẹn, nhưng nó không hoạt động không may. Bộ sưu tập của tôi kéo dài từ Mage_Core_Model_Resource_Db_Collection_Abstractvà tôi gặp lỗi Call to undefined method Mycompany_Module_Model_Resource_Mymodel_Collection::joinLeft(). Tôi đoán điều này là do tôi không sử dụng Mô hình tài nguyên EAV?
Celldweller

Sử dụng tham gia thay vì tham giaLeft, tôi đã chỉnh sửa câu trả lời
mageUz

doh! Tôi cảm thấy ngu ngốc bây giờ! ;-) Và tôi không biết tại sao tôi lại thử nó. Cảm ơn rât nhiều!
Celldweller

@Celldweller, bạn thậm chí không cần sử dụng $this->_map['fields']['sku'] = 'sku'hoặc tương tự trong trường hợp này. Bạn chỉ cần nó nếu bạn có một vài tên trường giống hệt nhau và cần thực hiện một bản dịch để ngăn ngừa xung đột. Nó chỉ thêm chi phí cho trường hợp sử dụng này. Trong trường hợp sử dụng khác, bạn có thể sử dụng $this->_map['fields']['my_sku'] = 'sku'sau đó bạn có thể sử dụng với bộ sưu tập và _prepareColumns: $this->addColumn('my_sku', array(…)), nó sẽ giúp bạn ngăn ngừa xung đột cho việc lọc hoặc sắp xếp cột nếu bạn có một trường skuđược sử dụng trong các bảng DB khác nhau cho bộ sưu tập
Sylvain Rayé

Câu trả lời chính xác! Nó có thể dẫn đến các vấn đề "mục có cùng ID đã tồn tại". Một cách đơn giản $this->getSelect()->group('main_table.product_id');giải quyết vấn đề, nhưng có lẽ mã có thể được tối ưu hóa, sao cho các bản sao không được tạo ngay từ đầu?
Simon

4

Xin chào Celldweller Tôi hy vọng bạn đang làm tốt :-)

Có thể bạn đã sai trong lời giải thích về lớp Mage_Core_Model_Resource_Db_Collection_Abstract, bạn mở rộng bộ sưu tập tài nguyên không phải mô hình vì bạn không được mở rộng mô hình với lớp bộ sưu tập nếu bạn muốn tôn trọng cấu trúc Magento. Tôi có đúng không

Dựa trên sự điều chỉnh của tôi, tôi thấy cách tiếp cận khác nhau, tùy thuộc vào tần suất bạn muốn nhận thuộc tính tên sản phẩm. Trong mọi trường hợp, tôi nghĩ thực hiện một truy vấn sql thông qua Magento Framework là cách tốt nhất và hiệu quả. Nó nhanh hơn để làm một Mage::getModel('catalog/product')->load(1234)->getName()cho mỗi mục được tải. Vì vậy, trên thực tế, nó sẽ rất giống với mã bạn sử dụng chosku

MÃ KHÔNG KIỂM TRA

Bạn muốn những thông tin đó mỗi khi bộ sưu tập được tải

Bạn có thể trong lớp bộ sưu tập của mình được đặt thành một _beforeLoadphương thức như một mã:

protected function _beforeLoad()
{
    $productName = Mage::getSingleton('eav/config')->getAttribute('catalog_product','name');

    $this->getSelect()
        ->join( array('product_attribute' => $productName->getBackendTable()),
            'main_table.product_id = product_attribute.entity_id',
            array())
        ->where("product_attribute.attribute_id = ?", $productName->getId());
    }

    return parent::_beforeLoad();
}

Bạn muốn những thông tin CHỈ cho lưới điện

Trong phần của bạn _prepareCollection, bạn sẽ phải thêm một phương thức trong bộ sưu tập của mình với cùng mã như đã được thực hiện ở trên vào _beforeLoadsau đó bạn có thể chuẩn bị bộ sưu tập bằng cách sử dụng phương thức này. Đừng sử dụng cả hai, ý tôi là không sử dụng cùng một mã _beforeLoadaddProductNamephương thức, chỉ sử dụng một trong số chúng. Đây là một mẫu:

Vào của bạn grid.php:

protected function _prepareCollection()
{
    ...
    $collection->addProductName();
    $this->setCollection($collection);
    return parent::_prepareCollection();
}

Vào Bộ sưu tập của bạn.php:

public function addProductName()
{
    $productName = Mage::getSingleton('eav/config')->getAttribute('catalog_product','name');

    $this->getSelect()
        -> join( array('product_attribute' => $productName->getBackendTable()),
            'main_table.product_id = product_attribute.entity_id',
            array())
        ->where("product_attribute.attribute_id = ?", $productName->getId());

    return $this;
}

Thật tuyệt khi đọc lại bạn :-) Cảm ơn bạn rất nhiều nhưng tôi không thể sử dụng phương thức tham gia (). Tôi đoán nó là một phương pháp chỉ mô hình tài nguyên EAV? Bạn đã đúng, tôi đã không chính xác trong câu hỏi ban đầu của tôi. Tôi sẽ chỉnh sửa nó :)
Celldweller

Oh và btw: Tất nhiên tôi không muốn làm một sản phẩm-> load () trong tình huống như vậy. Bắn tôi đi nếu tôi dám! ;-) Mục tiêu của tôi là có tất cả trong một bộ sưu tập để có thể thực hiện sắp xếp và lọc trong lưới. Xem bản cập nhật trong bài viết ban đầu của tôi để biết thêm chi tiết.
Celldweller

Vì vậy, thay thế tham giaLeft bằng cách tham gia nhưng bạn đã chấp nhận câu trả lời khác mặc dù tôi đã trả lời đúng và là người đầu tiên trả lời :-(
Sylvain Rayé

Vâng, bạn đúng. Tôi đã rất vui vì cuối cùng nó đã hoạt động, đến nỗi tôi đã không nghĩ về nó. Tôi rất biết ơn cả hai bạn. Hy vọng bạn có thể tha thứ cho tôi! Tôi nợ bạn một chầu bia.
Celldweller

à không lo lắng Chúng tôi gặp bạn ở Berlin với niềm vui :-)
Sylvain Rayé

4

Tôi đã có vấn đề gần như tương tự, nhưng tôi không thể thêm một bình luận, vì tôi không có 50 danh tiếng. Tôi đã dành rất nhiều thời gian để cố gắng tìm ra điều gì sai (tôi đã sử dụng mã của Sylvain Rayé). Bộ sưu tập sản phẩm của tôi cho một số lý do được lọc. Vì vậy, tôi tìm thấy một lý do.

Nếu bạn sử dụng một số công cụ nhập khẩu (magmi, v.v.), chúng thường không tạo các thuộc tính trống cùng một lúc. Do đó, việc sử dụng ->where("product_attribute.attribute_id = ?", $productName->getId())các sản phẩm không có thuộc tính này sẽ biến mất khỏi lựa chọn.

Đúng cách là sử dụng joinLeftnhư thế:

$productName = Mage::getSingleton('eav/config')->getAttribute('catalog_product','name');

$this->getSelect()
     ->joinLeft(array('product_attribute' => $productName->getBackendTable()),
        "main_table.product_id = product_attribute.entity_id AND
         product_attribute.attribute_id = {$productName->getId()}",
        array());

Hy vọng điều này sẽ giúp được ai đó.


-2

Hiển thị thuộc tính tùy chỉnh trên lưới sản phẩm.

Vui lòng ghi đè khối này Mage_Adminhtml_Block_Catalog_ Productt_Grid trong tiện ích mở rộng của bạn và sao chép các hàm _prepareCollection và _prepareColumn vào tệp khối của tiện ích mở rộng của bạn.

Thêm mã bên dưới để chọn attribuet trong hàm _prepareCollection của lưới sản phẩm Mage_Adminhtml_Block_Catalog_ Productt_Grid trước dòng $ this-> setCollection ($ sưu tập).

$attributeCode = 'qc_status';//here your attribute code
        $collection->joinAttribute($attributeCode, 'catalog_product/'.$attributeCode, 'entity_id', null, 'left');
        $collection->addAttributeToSelect($attributeCode);

Và sau đó bên dưới mã cho cột trong hàm _prepareColumns của lưới.

$attributeCodeConfig ='qc_status';//Your attribute code...

        $attributeId = Mage::getResourceModel('eav/entity_attribute')->getIdByCode('catalog_product', $attributeCodeConfig);

        $attribute = Mage::getModel('catalog/resource_eav_attribute')->load($attributeId);
        $attributeData = $attribute->getData();
        $frontEndLabel = $attributeData['frontend_label'];

        $attributeOptions = $attribute->getSource()->getAllOptions();
        $b = new Mage_Catalog_Model_Resource_Eav_Attribute();
        $attributeOptions2 = array();
        foreach ($attributeOptions as $value) {
            if(!empty($value['value'])) {
                $attributeOptions2[$value['value']] = $value['label'];
            }

        }


        if(count($attributeOptions2) > 0) {
            $this->addColumn($attributeCodeConfig,
                array(
                    'header'=> Mage::helper('catalog')->__($frontEndLabel),
                    'width' => '80px',
                    'index' => $attributeCodeConfig,
                    'type'  => 'options',
                    'options' => $attributeOptions2,

            ));
        } else {
            $this->addColumn($attributeCodeConfig,
                array(
                    'header'=> Mage::helper('catalog')->__($frontEndLabel),
                    'width' => '80px',
                    'index' => $attributeCodeConfig,

            ));
        }

Thay đổi tập tin cốt lõi là không thực hành tốt. Tương tự chonew SomeModel()
sv3n

chúng tôi không phải thay đổi trong tệp lõi. chúng tôi có thể ghi đè lên khối đó (Mage_Adminhtml_Block_Catalog_ Productt_Grid) để thực hiện chức năng của chúng tôi
Savoo
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.