Pregunta

Estoy haciendo lo siguiente:

$productCollection = Mage::getModel('catalog/product')
    ->getCollection();

$productCollection
    ->addAttributeToFilter('my_attribute', 1);

my_attribute no está en las tablas planas, pero las tablas planas están habilitadas.

me siguen dando la colección completa.

La razón parece estar en \Mage_Catalog_Model_Resource_Product_Collection::addAttributeToSelect:

$columns = $this->getEntity()->getAttributeForSelect($attributeCode);

No se $this->getEntity() es una instancia de Mage_Catalog_Model_Resource_Product_Flat la que obtiene los campos planos -. Y si no se encuentra ninguno, simplemente devuelve null

¿Qué es una forma limpia para añadir un atributo no plana para el filtro de colección?

En mi caso no lo hace sentido, para añadir el atributo de la tabla plana.

¿Fue útil?

Solución

Usted puede unirse a la mesa necesaria mismo.

$productCollection = Mage::getModel('catalog/product')
->getCollection();

$table = Mage::getSingleton('eav/config')->getAttribute('catalog_product', 'my_attribute')->getBackend()->getTable();
$attributeId = Mage::getSingleton('eav/config')->getAttribute('catalog_product', 'my_attribute')->getAttributeId();

$productCollection->getSelect()->join(array('attributeTable' => $table), 'e.entity_id = attributeTable.entity_id', array('my_attribute' => 'attributeTable.value'))
                            ->where("attributeTable.attribute_id = ?", $attributeId)
                            ->where("attributeTable.value = ?", 1);

Es posible que desee unirse por store_id, también.

Otros consejos

Un truco (CE 1.6.2.0+) es pasar la condición de una matriz y aunque no lo crean esto funciona como está previsto:

$collection->addFieldToFilter(array(array('attribute' => 'my_attribute', 'eq' => 1)));

La razón funciona la respuesta de ColinM es debido al código en el método de app/code/core/Mage/Catalog/Model/Resource/Product/Collection.php addAttributeToFilter. Si se utiliza este formato de matriz, que no llama addAttributeToSelect. En el modo plana, addAttributeToSelect error de forma silenciosa si el atributo no está en la mesa plana.

(continuación es un refrito de mi respuesta en https://stackoverflow.com/questions/6271284/can-i-add-other-attributes-to-magentos-flat-product-catalog-table/17021620 - no soy es seguro que la etiqueta es para eso, pero sé yo he encontrado que es muy útil)

Yo quería una solución "limpia" para seleccionar el modo de colección plana y el filtrado de atributos que no son planas, que:

  • no requiere el atributo de tener los ajustes específicos de administrador (que podría ser añadido por un usuario, o se oculta en la parte delantera)
  • funciona tanto plana y modo no plana

He utilizado la colección de productos asociados, pero esto se aplica a cualquier colección de EAV.

A falta de código:

$_product = Mage::getModel('catalog/product')->loadByAttribute( 'sku', 'ABC123' );
$coll = $_product->getTypeInstance()->getAssociatedProductCollection()
    ->addAttributeToSelect( 'my_custom_attribute' )
    ->addAttributeToFilter( 'my_custom_attribute', 3 )
;

En la pantalla plana, el código anterior en silencio no selecciona o filtro en el atributo si sucede no estar en la mesa plana.

Adición al selecto:

$_product = Mage::getModel('catalog/product')->loadByAttribute( 'sku', 'ABC123' );
$coll = $_product->getTypeInstance()->getAssociatedProductCollection()
    ->joinAttribute( 'my_custom_attribute', 'catalog_product/my_custom_attribute', 'entity_id', null, 'left' )
    ->addAttributeToSelect( 'my_custom_attribute' )
;

El método joinAttribute agrega un join a la consulta para el atributo específico solicitado. Todavía funciona cuando el atributo ya está en la mesa plana, pero será un poco menos eficiente que simplemente usando la tabla plana.

He usado un left unirse a allí, para asegurarse de que obtiene productos si my_custom_attribute no se establece en esos productos. Cambio que para inner si sólo está interesado en filas en las que se establece my_custom_attribute.

Adición al filtro (como por ColinM arriba):

$_product = Mage::getModel('catalog/product')->loadByAttribute( 'sku', 'ABC123' );
$coll = $_product->getTypeInstance()->getAssociatedProductCollection()
    ->addAttributeToFilter( array( array( 'attribute' => 'my_custom_attribute', 'eq' => 3 ) ) )
;

El código anterior se añadirá a la seleccione, así como la obediencia a su filtro.

(probado en CE 1.6.2.0)

En el módulo Mage_Rss que utiliza el hacky un método para desactivar las tablas planas. Utilizan el hecho, que las tablas planas son siempre apagado en el almacén de administración y por lo que sólo emulan el almacén de administración.

class Mage_Rss_Helper_Data {

[...]

/**
 * Disable using of flat catalog and/or product model to prevent limiting results to single store. Probably won't
 * work inside a controller.
 *
 * @return null
 */
public function disableFlat()
{
    /* @var $flatHelper Mage_Catalog_Helper_Product_Flat */
    $flatHelper = Mage::helper('catalog/product_flat');
    if ($flatHelper->isEnabled()) {
        /* @var $emulationModel Mage_Core_Model_App_Emulation */
        $emulationModel = Mage::getModel('core/app_emulation');
        // Emulate admin environment to disable using flat model - otherwise we won't get global stats
        // for all stores
        $emulationModel->startEnvironmentEmulation(0, Mage_Core_Model_App_Area::AREA_ADMINHTML);
    }
}

Después de iniciar la emulación que debe reiniciarlo con emulationModel->stopEnvironmentEmulation()

cuando se crea el atributo que debería estar en el nivel global y filtrable. De esta manera se podrá utilizar en la navegación layared. También se requiere el atributo de ser una lista desplegable o de selección múltiple. Yo personalmente consejos en contra de cambiar los archivos principales para satisfacer sus necesidades en este caso

Licenciado bajo: CC-BY-SA con atribución
No afiliado a magento.stackexchange
scroll top