Pregunta

Tengo dos entidades con un mapeo unidireccional de muchos a uno.

Aquí está Product:

use Doctrine\Common\Collections\ArrayCollection;

/**
 * @Entity
 * @Table(name="Product")
 * @gedmo:TranslationEntity(class="GPos_Model_Translation_ProductTranslation")
 */
class GPos_Model_Product extends GPos_Doctrine_ActiveEntity {
    /**
     * @Id @Column(type="integer")
     * @GeneratedValue
     */
    protected $id;

    /**
     * @ManyToMany(targetEntity="GPos_Model_Category")
     * @JoinTable(name="products_categories",
     *      joinColumns={@JoinColumn(name="product_id", referencedColumnName="id")},
     *      inverseJoinColumns={@JoinColumn(name="category_id", referencedColumnName="id")}
     *      )
     */
    protected $categories;

    public function __construct() {
        $this->categories = new ArrayCollection();
    }

    public function addCategory(GPos_Model_Category $category) {
        if (!$this->categories->contains($category))
            $this->categories->add($category);
    }
}

Como puede ver, $ Category es un ArrayCollection de las entidades gpos_model_category.

ahora que? Bueno, ahora me gustaría recuperar todos los productos que se encuentran en una categoría determinada y también todos los productos que son no en una categoría dada.

He intentado $products = GPos_Model_Product::findByCategories($category->getId()); pero eso solo me dio El ID de SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '= '1'' at line 1 y $category es 1, así que supongo que no es la forma de ir.¿Alguien sabe cómo lidiar con eso?

¡Gracias!

¿Fue útil?

Solución

finalmente descubrí cómo seleccionar todos los productos que están en una categoría gracias a https://stackoverflow.com/a/9808277 / 1300454 .

Afligido un poco su solución para poder pasar una variedad de entidades de categoría y encontraría todos los productos que estén dentro de estas categorías. Si da más de una entidad, devolverá cualquier producto que esté en al menos una de las categorías dadas.

Aquí está My Tweak (localizo esta función en la entidad de mi producto):

/**
 *
 * Takes an array of GPos_Model_Category entities as parameter and returns all products in these categories
 * @param array $categories
 */
public static function findByCategories($categories) {
    $categoryArray = array();
    foreach ($categories as $category) {
        array_push($categoryArray, $category->getId());
    }
    $qb = Zend_Registry::get('entityManager')->createQueryBuilder();
    $qb ->select('p')
    ->from('GPos_Model_Product', 'p')
    ->leftJoin('p.categories', 'c')
    ->andWhere($qb->expr()->in('c.id', $categoryArray));

    return $qb->getQuery()->execute();;
}

Aquí es cómo lo llamas:

$products_cat = GPos_Model_Product::findByCategories(array($category));

En este caso, la categoría es una entidad, solo es por eso que lo puse en una matriz antes de darlo a la función.

Y aquí es la forma en que encuentra productos que no están en una categoría dada o en la lista de categoría:

/**
 *
 * Takes an array of GPos_Model_Category entities as parameter and returns all products not in these categories
 * @param array $categories
 */
public static function findByNotCategories($categories) {
    $categoryArray = array();
    foreach ($categories as $category) {
        array_push($categoryArray, $category->getId());
    }
    $qb = Zend_Registry::get('entityManager')->createQueryBuilder();
    $qb2 = Zend_Registry::get('entityManager')->createQueryBuilder();
    $qb->select('p')
    ->from('GPos_Model_Product', 'p')
    ->where($qb->expr()->notIn('p.id',
        $qb2->select('p2.id')
        ->from('GPos_Model_Product', 'p2')
        ->leftJoin('p2.categories', 'c')
        ->andWhere($qb->expr()->in('c.id', $categoryArray))
        ->getDQL()
    ));

    return $qb->getQuery()->execute();
}

Esto realmente está utilizando una subselección. Estoy seleccionando todas las identificaciones de productos que están en la categoría dada (esa es la subselección), entonces estoy seleccionando todos los productos que no están en el resultado de la subselección. ¡Mi trabajo aquí está hecho!

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