Mazaka
Mazaka

Reputation: 634

Symfony Doctrine cross-reference table with array of ids

I have two Entities User and Items the user entity has a array of item ids stored in $item_ids now what I want is when the user is fetched the items are also fetched and for example stored in $item_storage.

Is this possible with annotations like OneToMany / ManyToOne / ManyToMany or do I need to make a custom Entity Repository class to do this?

To Clearify. As result I would like to be able to do the following

// ...

/**
 * @Route("/show/", name="show")
 */
public function showAction()
{

    $user= $this->getDoctrine()->getManager()
        ->getRepository('AppBundle\\Entity\\User')
        ->findOneById(1);

    return $this->render('show/multi_array.html.twig', array(
        'user' => $user->getName(),
        'multi_array' => $user->getItemStorage(), // should return a array of Items 

    ));

}

// ...

The $user->getItemStorage array I would like to get back looks something like this

Array
(
    [0] => Array
        (
            [id] => 1
            [name] => Item One
            [more_cols] => more data
        )

    [1] => Array
        (
            [id] => 2
            [name] => Item Two
            [more_cols] => more data
        )

)

Database entries would look something like

User Table
| Id | Name | Item_ids                       |
| 1  | Me   | a:2:{i:0;s:1:"1";i:1;s:1:"2";} |

Items Table
| Id | Name     | More_cols |
| 1  | Item One | more data |
| 2  | Item Two | more data |

The User Entity

<?php
// src/AppBundle/Entity/User.php
namespace AppBundle\Entity;

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

/**
 * @ORM\Entity
 * @ORM\Table(name="users")
 */
class User
{

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\Column(type="string")
     */
    protected $name;

    /**
     * @ORM\Column(type="array")
     */
    protected $item_ids;

    protected $item_storage;

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


    // ...
}

The Item Entity

<?php
// src/AppBundle/Entity/Items.php
namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="users")
 */
class Items
{

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\Column(type="string")
     */
    protected $name;

    /**
     * @ORM\Column(type="string")
     */
    protected $more_cols;

    // ...
}

Upvotes: 0

Views: 1734

Answers (1)

Isabek Tashiev
Isabek Tashiev

Reputation: 1044

As @Ivan said you can use OneToMany and ManyToMany depending on your business logic. For example I have used OneToMany relationship.

class User
{

    /**
     * @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, unique=true)
     */
    private $name;


    /**
     * @ORM\OneToMany(targetEntity="Items", mappedBy="user", cascade={"persist", "remove"})
     */
    private $items;

    //Getters and setters
}

And entity Items.

class Items
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string")
     */
    protected $name;

    /**
     * @ORM\Column(type="string")
     */
    protected $more_cols;

    /**
     * @ORM\ManyToOne(targetEntity="User", inversedBy="items")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     */
    protected $user;

    //Getters and setters
}

You can get user`s items like this:

 $user->getItems();

But result will not be array of array's, will be array of objects.

 forearch($user->getItems() as $item)
 {
    $item->getName();
    $item->getMoreTools();
 }

Upvotes: 2

Related Questions