Mam niestandardową tabelę z odniesieniem do produktu product_id
. Teraz chciałbym wyświetlić informacje o produkcie (SKU, nazwa) w siatce wewnętrznej bazy danych , ale nie jestem pewien, jaka jest najlepsza praktyka, aby to zrobić?
Moje najlepsze przypuszczenie SKU
brzmi następująco:
$collection->join(
'catalog/product',
'product_id=`catalog/product`.entity_id',
array('product_sku' => 'sku')
)
(kod z _prepareCollection()
metody w mojej klasie bloków grid)
Ale co z nazwą produktu? Można go znaleźć w catalog_product_entity_varchar. Rozumiem, że możesz raczej łatwo go zdobyć, jeśli twój własny model zasobów i kolekcja jest oparta, Mage_Eav_Model_Entity_Collection_Abstract
ponieważ wtedy możesz użyć metod takich jak joinAttribute
. Ale mój model opiera się na prostej tabeli i jest rozszerzany Mage_Core_Model_Resource_Db_Collection_Abstract
i nie ma joinAttribute
dostępnej metody.
Więc jaki jest najlepszy sposób na uzyskanie nazwy produktu w tym przypadku?
Dziękuję za poświęcony czas i pomoc :-)
Aktualizacja: Mówiąc ściślej, mówiłem o moim modelu zasobów i kolekcji. Pasuje do prostego płaskiego stołu z zaledwie kilkoma atrybutami
entity_id product_id created_at user_id
Moim zamiarem jest gridowanie w backendie, gdzie pokazuję statystyki:
ProductSku Count(ProductSku) MAX(created_at)
O ile mi wiadomo, najlepszym podejściem do tego jest klasa bloków grid, a metodą jest _prepareCollection()
.
Moja metoda wygląda następująco:
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();
}
Działa to dobrze dla SKU (które w _prepareColums()
metodzie nazywam product_sku . Ale co join
muszę tu wstawić, aby uzyskać nazwę (i np. Producenta)?
Czy robię coś źle, ponieważ nie mogę użyć joinLeft()
?
źródło
Mage_Core_Model_Resource_Db_Collection_Abstract
i pojawia się błądCall to undefined method Mycompany_Module_Model_Resource_Mymodel_Collection::joinLeft()
. Chyba dlatego, że nie używam modelu zasobów EAV?$this->_map['fields']['sku'] = 'sku'
w tym przypadku nie musisz nawet używać lub podobnie. Potrzebujesz go tylko wtedy, gdy masz kilka identycznych nazw pól i musisz wykonać tłumaczenie, aby zapobiec konfliktom. Po prostu dodaje narzut dla tego przypadku użycia. W innym przypadku użycia możesz użyć,$this->_map['fields']['my_sku'] = 'sku'
a następnie możesz użyć z kolekcją i_prepareColumns
:$this->addColumn('my_sku', array(…))
pomoże to uniknąć konfliktu podczas filtrowania lub sortowania kolumn, jeśli masz polesku
używane w różnych tabelach DB wspólnych dla kolekcji$this->getSelect()->group('main_table.product_id');
rozwiązuje problem, ale może kod można zoptymalizować, aby duplikaty nie były tworzone w pierwszej kolejności?Cześć Celldweller Mam nadzieję, że masz się dobrze :-)
Być może myliłeś się w wyjaśnieniach na temat klasy
Mage_Core_Model_Resource_Db_Collection_Abstract
, rozszerzasz kolekcję zasobów, a nie model, ponieważ nie możesz rozszerzać modelu o klasę kolekcji, jeśli chcesz uszanować strukturę Magento. Czy mam rację?Na podstawie mojej korekty widzę różne podejście, w zależności od tego, jak często chcesz uzyskać atrybut nazwy produktu. W każdym razie myślę, że wykonanie zapytania SQL za pomocą Magento Framework jest najlepszym sposobem i wydajne. Jest to szybsze niż wykonanie
Mage::getModel('catalog/product')->load(1234)->getName()
dla każdego załadowanego elementu. W rzeczywistości będzie bardzo podobny do kodu używanego dosku
KOD NIE TESTOWANY
Chcesz te informacje za każdym razem, gdy ładowana jest kolekcja
Możesz w swojej klasie kolekcji ustawić na
_beforeLoad
metodę taki kod:Chcesz te informacje TYLKO dla siatki
W twoim
_prepareCollection
będziesz musiał dodać metodę do swojej kolekcji z tym samym kodem, jak to zostało zrobione powyżej, a_beforeLoad
następnie możesz przygotować kolekcję za pomocą tej metody. Nie używaj obu, to znaczy nie używaj razem tego samego kodu_beforeLoad
iaddProductName
metod, użyj tylko jednego z nich. Oto próbka:W twoje
grid.php
:Do twojej kolekcji.php:
źródło
Miałem prawie ten sam problem, ale nie mogę dodać komentarza, ponieważ nie mam 50 reputacji. Spędziłem dużo czasu próbując dowiedzieć się, co jest nie tak (użyłem kodu Sylvaina Rayé). Moja kolekcja produktów z jakiegoś powodu została odfiltrowana. Więc znalazłem powód.
Jeśli używasz niektórych narzędzi do importowania (magmi itp.), Często nie tworzą one jednocześnie pustych atrybutów. Dlatego używanie
->where("product_attribute.attribute_id = ?", $productName->getId())
produktów, które nie mają tego atrybutu, zniknie z wyboru.Właściwy sposób polega na użyciu w
joinLeft
ten sposób:Mam nadzieję, że to komuś pomoże.
źródło
Wyświetl niestandardowy atrybut w siatce produktu.
Zastąp ten blok Mage_Adminhtml_Block_Catalog_Product_Grid w swoim rozszerzeniu i skopiuj funkcje _prepareCollection i _prepareColumns do pliku bloku rozszerzenia.
Dodaj poniższy kod, aby wybrać atrybut w _prepareCollection funkcji siatki produktu Mage_Adminhtml_Block_Catalog_Product_Grid przed wierszem $ this-> setCollection ($ collection).
A następnie poniżej kodu dla kolumny w _prepareColumns funkcji siatki.
źródło
new SomeModel()