Eu tenho uma tabela personalizada com uma referência de produto product_id
. Agora, gostaria de mostrar informações do produto (sku, nome) na minha grade de back-end , mas não tenho certeza qual é a melhor prática para fazer isso?
Meu melhor palpite SKU
é o seguinte:
$collection->join(
'catalog/product',
'product_id=`catalog/product`.entity_id',
array('product_sku' => 'sku')
)
(código do _prepareCollection()
método na minha classe de bloco de grade)
Mas e o nome do produto? Pode ser encontrado em catalog_product_entity_varchar. Meu entendimento é que você pode obtê-lo com bastante facilidade se o seu próprio modelo e coleção de recursos for baseado, Mage_Eav_Model_Entity_Collection_Abstract
porque então você poderá usar métodos como joinAttribute
. Mas meu modelo é baseado em uma tabela simples e se estende a partir de Mage_Core_Model_Resource_Db_Collection_Abstract
e não há joinAttribute
método disponível.
Então, qual é a melhor maneira de obter o nome do produto nesse caso?
Obrigado pelo seu tempo e ajuda :-)
Atualização: para ser mais preciso, eu estava falando sobre meu modelo e coleção de recursos. Combina uma tabela plana simples com apenas alguns atributos, como
entity_id product_id created_at user_id
Minha intenção é fazer uma grade no back-end, onde mostro algumas estatísticas:
ProductSku Count(ProductSku) MAX(created_at)
Até onde eu sei, a melhor maneira de fazer isso é através da classe de blocos de grade e o método a seguir é _prepareCollection()
.
Meu método fica assim:
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();
}
Isso funciona bem para o sku (que eu me refiro como product_sku no _prepareColums()
método. Mas o join
que preciso inserir aqui para obter o nome (e, por exemplo, o fabricante)?
Estou fazendo algo errado porque não posso usar joinLeft()
?
fonte
Mage_Core_Model_Resource_Db_Collection_Abstract
e recebo um erroCall to undefined method Mycompany_Module_Model_Resource_Mymodel_Collection::joinLeft()
. Eu acho que isso é porque eu não uso um modelo de recursos EAV?$this->_map['fields']['sku'] = 'sku'
ou semelhante nesse caso. Você precisará apenas se tiver vários nomes de campos idênticos e precisar fazer uma tradução para evitar conflitos. Apenas adicionando sobrecarga para este caso de uso. Em um caso de uso diferente, você pode usar$this->_map['fields']['my_sku'] = 'sku'
, então você pode usar com a recolha e_prepareColumns
:$this->addColumn('my_sku', array(…))
, ele vai ajudar você a evitar os conflitos para a filtragem ou colunas de classificação se você tiver um camposku
usado em diferentes tabelas de banco de dados comum para a coleção$this->getSelect()->group('main_table.product_id');
resolve o problema, mas talvez o código possa ser otimizado, para que duplicatas não sejam criadas em primeiro lugar?Oi Celldweller Espero que você esteja bem :-)
Talvez você tenha se enganado em sua explicação sobre a classe
Mage_Core_Model_Resource_Db_Collection_Abstract
, você estende uma coleção de recursos e não o modelo porque não deve estender um modelo com uma classe de coleção se quiser respeitar a estrutura do Magento. Estou certo?Com base na minha correção, vejo diferentes tipos de abordagem, dependendo da frequência com que você deseja obter o atributo de nome do produto. De qualquer forma, acho que fazer uma consulta sql através do Magento Framework é a melhor maneira e eficiente. É mais rápido do que fazer um
Mage::getModel('catalog/product')->load(1234)->getName()
para cada item carregado. Portanto, de fato, será muito semelhante ao código usado para osku
CÓDIGO NÃO TESTADO
Você deseja essas informações sempre que uma coleção é carregada
Em sua classe de coleção, você pode definir um
_beforeLoad
método como esse código:Você deseja essas informações apenas para a grade
No seu
_prepareCollection
, você precisará adicionar um método em sua coleção com o mesmo código que foi feito acima para_beforeLoad
poder preparar a coleção usando esse método. Não use os dois, quero dizer, não use o mesmo código_beforeLoad
eaddProductName
métodos juntos , use apenas um deles. Aqui está uma amostra:No seu
grid.php
:Em seu Collection.php:
fonte
Eu tive quase o mesmo problema, mas não posso adicionar um comentário, porque não tenho 50 reputação. Passei muito tempo tentando descobrir o que estava errado (usei o código de Sylvain Rayé). Por algum motivo, minha coleção de produtos foi filtrada. Então eu encontrei um motivo.
Se você estiver usando algumas ferramentas de importação (magmi, etc), elas geralmente não criam atributos vazios de uma só vez. Portanto, o uso de
->where("product_attribute.attribute_id = ?", $productName->getId())
produtos que não possuem esse atributo desaparecerá da seleção.O caminho certo é usar
joinLeft
assim:Espero que isso ajude alguém.
fonte
Exibir atributo personalizado na grade do produto.
Sobrescreva esse bloco Mage_Adminhtml_Block_Catalog_Product_Grid em suas funções de extensão e cópia _prepareCollection e _prepareColumns no arquivo de bloco da sua extensão.
Adicione o código abaixo para selecionar o atributo na função _prepareCollection da grade do produto Mage_Adminhtml_Block_Catalog_Product_Grid antes da linha $ this-> setCollection ($ collection).
E, em seguida, abaixo do código da coluna na função _prepareColumns da grade.
fonte
new SomeModel()