Symfony Relations - PullRequest
       3

Symfony Relations

0 голосов
/ 12 сентября 2018

В моем приложении у меня есть 3 объекта; Пользователь, бронирование и номер.

субъект бронирования:

namespace App\Entity;

/**
 * @ORM\Table(name="booking")
 * @ORM\Entity(repositoryClass="App\Repository\BookingRepository")
 */
class Booking
{
/**
 * @ORM\Column(type="boolean")
 * @Assert\NotBlank()
 */
private $isActive;

/**
 * @ORM\ManyToOne(targetEntity="App\Entity\Room", inversedBy="bookings")
 */
private $room;

/**
 * @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="bookings")
 */
private $user;

Номер объекта:

/**
 * @ORM\Table(name="room")
 * @ORM\Entity(repositoryClass="App\Repository\RoomRepository")
 */
class Room
{
/**
 * @ORM\OneToMany(targetEntity="App\Entity\Booking", mappedBy="room")
 * @Expose
 */
private $bookings;

Пользователь:

/**
 * @ORM\Table(name="app_user")
 * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
 * @UniqueEntity(fields="email", message="This email address is already in use")
 */
class User implements AdvancedUserInterface
{

/**
 * @ORM\Column(type="string", length=255, unique=true)
 * @Assert\NotBlank()
 * @Assert\Email()
 */
private $email;

/**
 * @ORM\OneToMany(targetEntity="App\Entity\Booking", mappedBy="user")
 * @Expose
 */
private $bookings;

Учитывая электронную почту пользователя, я могу получить номер комнаты, подобный этому:

    $user = $this->getEntityManager()
        ->getRepository(User::class)
        ->findOneBy([
            'email' => 'johndoe@domain.com'
        ]);

    $booking = $this->getEntityManager()
        ->getRepository(Booking::class)
        ->findOneBy([
            'user' => $user,
            'isActive' => true,
        ]);

    $roomId = $booking->getRoom()->getId();

Однако это, похоже, долгий путь. Можно ли оптимизировать это и запросить номер, не совершая двух вызовов базы данных?

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Вы можете использовать один запрос на присоединение, чтобы получить комнату для конкретного пользователя

$this->getEntityManager()
    ->createQueryBuilder()
    ->select('r')
    ->from(Room::class, 'r')
    ->join('r.bookings', 'b')
    ->join('b.user', 'u')
    ->where('u.email = :email')
    ->andWhere('b.isActive = :isActive')
    ->setParameter('isActive', true)
    ->setParameter('email', 'johndoe@domain.com')
    ->getQuery()
    ->getResult();
0 голосов
/ 12 сентября 2018

Да, вы можете получить его непосредственно из переменной $user. Я не вижу здесь никаких методов получения или установки, но я предполагаю, что вы их создали. Если это так, то вы можете сделать следующее:

$bookings = $user->getBookings();

Бронирование - это массив, поэтому вам нужно будет выбрать, для какого бронирования вы хотите получить номер. Давайте просто выберем первое:

$roomId = $bookings->first()->getRoom()->getId()

Чтобы сделать его чище, вы можете добавить метод getCurrentBooking или что-то похожее на ваш класс User, который будет возвращать именно то бронирование, которое вы хотите.

Тогда вы получите что-то вроде этого:

$roomId = $user->getCurrentBooking->getRoom()->getId()

...