Как использовать Doctrine Embeddables

Я пытаюсь использовать встраиваемые модули Doctrine в проекте Symfony 2.

У меня есть класс Purchase, где у меня есть поле price, которое является встраиваемым:

/**
 * Products
 *
 * @ORM\Table(name="purchases")
 * @ORM\Entity
 */
class Purchase
{
    /**
     *
     * @ORM\Embedded(class="AppBundle\Entity\Embeddable\PriceEmbeddable")
     */
    private $price;

    /**
     * Set price
     *
     * @param MoneyInterface $price
     * @return $this
     */
    public function setPrice(MoneyInterface $price)
    {
        $this->price = $price;

        return $this;
    }

    /**
     * Get price
     *
     * @return MoneyInterface|float
     */
    public function getPrice()
    {
        return $this->price;
    }

}

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

/**
 * @ORM\Embeddable
 */
class PriceEmbeddable
{
    /** @ORM\Column(type = "integer") */
    private $amount;

    /** @ORM\Column(type = "string") */
    private $currency;
}

Теперь схема в базе данных создается правильно, но при сохранении объекта Purchase я получаю следующую ошибку:

SQLSTATE [23000]: нарушение ограничения целостности: 1048 Столбец «price_amount» не может быть нулевым

И я верю в это: я пока не понимаю, как работает механизм.

Как установить и получить значения из «реального» объекта (Purchase)?

Я передаю значение как объект Money (объект значения Я использую) для метода setPrice() в Purchaseentity, но как это значение разбивается на два свойства amount и currency и устанавливается во встраиваемом классе?

Поскольку, выполняя var_dump (используя функцию dump() из VarDumper), я получаю Объект установлен правильно:

PurchaseListener.php on line 58:
Purchase {#1795 ▼
  ...
  -price: Money {#1000 ▼
    -amount: 86
    -currency: Currency {#925 ▼
      -currencyCode: "EUR"
    }
  }
}

Но эти значения не установлены во встроенном компоненте, и я не понимаю, почему...

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

/**
 * @ORM\Embeddable
 */
class PriceEmbeddable
{
    /** @ORM\Column(type = "integer") */
    private $amount;

    /** @ORM\Column(type = "string") */
    private $currency;

    public function __construct($value)
    {
        $this->currency = 'EUR';
        $this->amount = 90;
    }

    public function setAmount($amount)
    {
        $this->amount = $amount = 90;
    }

    public function setCurrency($currency)
    {
        $this->currency = $currency = 'EUR';
    }

    public function getAmount()
    {
        return $this->amount;
    }

    public function getCurrency()
    {
        return $this->currency;
    }
}

person Aerendir    schedule 28.08.2015    source источник


Ответы (2)


Это простое решение:

/**
 * Products
 *
 * @ORM\Table(name="purchases")
 * @ORM\Entity
 */
class Purchase
{
    /**
     *
     * @ORM\Embedded(class="AppBundle\Entity\Embeddable\PriceEmbeddable")
     */
    private $price;

    /**
     * Set price
     *
     * @param PriceEmbeddable $price
     * @return $this
     */
    public function setPrice(PriceEmbeddable $price)
    {
        $this->price = $price;

        return $this;
    }

    /**
     * Get price
     *
     * @return PriceEmbeddable
     */
    public function getPrice()
    {
        return $this->price;
    }

}
person Aerendir    schedule 29.08.2015

Вы должны явно создать экземпляр PriceEmbeddable в своем конструкторе Purchase:

class Purchase
{
  ...

  function __construct() {
      $this->price = new PriceEmbeddable();
  }

  ...

}
person psylosss    schedule 02.02.2021