[ alfa-pro @ 10.03.2014. 12:57 ] @
Drustvo imam problem oko prikazivanja kategorije nekog proizvoda, u mom slucaju kategorija je Type a proizvod je Item. Upitanju je menu system koji ima iteme i typove.
Tipovi su npr (top-menu, footer-menu, user-menu) a itemi su (home, contact, about-us etc..)
Sto se tice ManyToOne i Join to je sve po PS-u uradjeno samo problem nastaje kada hocu da prikazem odredjeni tip za odredjeni item.
Ja uspeno izlistam iz baze sve informacije ali kada hocu da prikazem odredjeni tip za odredjeni item ja sam ogranicen da moram koristiti find(int) metodu i tako da mi svaki item ima isti tip.

Moji Entiteti su :

MenuType.php

<
Code:
?php

namespace ISLab\AdminBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * MenuType
 *
 * @ORM\Table(name="menu_type")
 * @ORM\Entity(repositoryClass="ISLab\AdminBundle\Entity\MenuTypeRepository")
 */
class MenuType
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;

    /**
     * @var string
     *
     * @ORM\Column(name="description", type="string", length=255, nullable=true)
     */
    private $description;

    /**
     * @var integer
     *
     * @ORM\Column(name="status", type="integer", nullable=true)
     */
    private $status;

    /**
     * @ORM\OneToMany(targetEntity="ISLab\AdminBundle\Entity\MenuItem", mappedBy="type")
     */
    protected $items;
    
    public function __construct() {
        $this->items = new ArrayCollection();
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return MenuType
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set description
     *
     * @param string $description
     * @return MenuType
     */
    public function setDescription($description)
    {
        $this->description = $description;

        return $this;
    }

    /**
     * Get description
     *
     * @return string 
     */
    public function getDescription()
    {
        return $this->description;
    }

    /**
     * Set status
     *
     * @param integer $status
     * @return MenuType
     */
    public function setStatus($status)
    {
        $this->status = $status;

        return $this;
    }

    /**
     * Get status
     *
     * @return integer 
     */
    public function getStatus()
    {
        return $this->status;
    }

    /**
     * Add items
     *
     * @param \ISLab\AdminBundle\Entity\MenuItem $items
     * @return MenuType
     */
    public function addItem(\ISLab\AdminBundle\Entity\MenuItem $items)
    {
        $this->items[] = $items;

        return $this;
    }

    /**
     * Remove items
     *
     * @param \ISLab\AdminBundle\Entity\MenuItem $items
     */
    public function removeItem(\ISLab\AdminBundle\Entity\MenuItem $items)
    {
        $this->items->removeElement($items);
    }

    /**
     * Get items
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getItems()
    {
        return $this->items;
    }
}



MenuItem.php

Code:

<?php

namespace ISLab\AdminBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * MenuItem
 *
 * @ORM\Table(name="menu_item")
 * @ORM\Entity(repositoryClass="ISLab\AdminBundle\Entity\MenuItemRepository")
 */
class MenuItem
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var integer
     *
     * @ORM\Column(name="parent", type="integer", nullable=true)
     */
    private $parent;

    /**
     * @ORM\ManyToOne(targetEntity="ISLab\AdminBundle\Entity\MenuType", inversedBy="items")
     * @ORM\JoinColumn(name="type", referencedColumnName="id")
     */
    private $type;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;

    /**
     * @var string
     *
     * @ORM\Column(name="route", type="string", length=255, nullable=true)
     */
    private $route;

    /**
     * @var integer
     *
     * @ORM\Column(name="status", type="integer", nullable=true)
     */
    private $status;

    /**
     * @var string
     *
     * @ORM\Column(name="options", type="text", nullable=true)
     */
    private $options;


    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set parent
     *
     * @param integer $parent
     * @return MenuItem
     */
    public function setParent($parent)
    {
        $this->parent = $parent;

        return $this;
    }

    /**
     * Get parent
     *
     * @return integer 
     */
    public function getParent()
    {
        return $this->parent;
    }

    /**
     * Set type
     *
     * @param integer $type
     * @return MenuItem
     */
    public function setType($type)
    {
        $this->type = $type;

        return $this;
    }

    /**
     * Get type
     *
     * @return integer 
     */
    public function getType()
    {
        return $this->type;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return MenuItem
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set route
     *
     * @param string $route
     * @return MenuItem
     */
    public function setRoute($route)
    {
        $this->route = $route;

        return $this;
    }

    /**
     * Get route
     *
     * @return string 
     */
    public function getRoute()
    {
        return $this->route;
    }

    /**
     * Set status
     *
     * @param integer $status
     * @return MenuItem
     */
    public function setStatus($status)
    {
        $this->status = $status;

        return $this;
    }

    /**
     * Get status
     *
     * @return integer 
     */
    public function getStatus()
    {
        return $this->status;
    }

    /**
     * Set options
     *
     * @param string $options
     * @return MenuItem
     */
    public function setOptions($options)
    {
        $this->options = $options;

        return $this;
    }

    /**
     * Get options
     *
     * @return string 
     */
    public function getOptions()
    {
        return $this->options;
    }
}



Za sam prikaz svih itema imam repository metodu koja sadrzi :

Code:

    /**
     * Fetch All Menu Items
     * 
     */
    public function findAllMenuItemsById()
    {
        $query = 'SELECT i FROM ISLabAdminBundle:MenuItem i ORDER by i.id ASC';
        
        return $this->getEntityManager()->createQuery($query)
                ->getArrayResult();
    }


I sada u kontroleru pozivam repository klasu koja mi izlistava sve iteme
Code:

    /**
     * Menu Index
     * 
     * This will fetch all menu items and types
     * 
     */
    public function indexAction() 
    {   
        $items = $this->getDoctrine()->getRepository('ISLabAdminBundle:MenuItem')->findAllMenuItemsById();
        $types = $this->getDoctrine()->getRepository('ISLabAdminBundle:MenuType')->fetchAllMenuTypesByName();
    
        return $this->render('ISLabAdminBundle:Menu:index.html.twig', 
                array('menu_types' => $types,
                      'menu_items' => $items
                ));
    }


Problem nastaje sada kada ja hocu za svaki item da prikazem odredjeni tip. Doctrine zahteva da koristim metodu find koja ocekuje ID. Ako pozovem find i postavim 1
meni onda svaki item ima istu vrednost tipa koji ima id 1. U mom slucaju id =1 je top menu.

Evo primer:

Code:
    public function indexAction() 
    {   
        $items = $this->getDoctrine()->getRepository('ISLabAdminBundle:MenuItem')->findAllMenuItemsById();
        $types = $this->getDoctrine()->getRepository('ISLabAdminBundle:MenuType')->fetchAllMenuTypesByName();
        
        $item_type = $this->getDoctrine()->getRepository('ISLabAdminBundle:MenuItem')->find(1); // <----
        
        $type_name = $item_type->getType()->getName();
    
        return $this->render('ISLabAdminBundle:Menu:index.html.twig', 
                array('menu_types' => $types,
                      'menu_items' => $items,
                      'type_name' => $type_name
                ));
    }


Ako stavim : $item_type = $this->getDoctrine()->getRepository('ISLabAdminBundle:MenuItem')->find(1); Svi itemi imaju vrednost Top Menu ako stavim 2 svi imaju User Menu.




Kako i na koji nacin da automacki uskocim u type tabelu i prikazem ime tipa za svakog posbno?
[ Nikola Poša @ 10.03.2014. 17:46 ] @
Ne kapiram što uopšte pokušavaš na taj način... Zašto ne koristiš JOIN?

Ako sam dobro razumeo, imaš vezu tipova menija i stavki u njima, jedan na više, odnosno više na jedan, u zavisnosti s koje strane gledaš. Znači u tom tvom repository-u za Menu Item-e, dodaj ovakav neki metod:
Code:
public function getMenuItems()
{
    $queryBuilder = $this->createQueryBuilder('i');
    $queryBuilder->select('i', 't');
    $queryBuilder->join('i.type', 't');
    
    return $queryBuilder->getQuery()->getResult();
}

To bi trebalo da ti vrati sve menu item-e, ali sa odgovarajućim menu tipovima, upisanim u $type property svakog item-a u rezultujućoj listi, budući da si na taj način definisao vezu između ta dva entiteta.