ArrayCollection объектов, расширяющих абстрактный MappedSuperClass

Я создаю генератор форм, используя Symfony 2.2 с Doctrine.

Мои сущности следующие:

  • Форма
  • Текст виджета
  • ВиджетВыбрать

Все мои виджеты расширяют следующий класс:

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

    /**
     * @ORM\ManyToOne(targetEntity="Form", inversedBy="widgets")
     */
    private $form;

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

    /**
     * @var integer
     *
     * @ORM\OneToOne(targetEntity="Question")
     */
    private $question;

    // getters and setters
}

Сущность моей формы выглядит так:

/**
 * Form
 *
 * @ORM\Table(name="form")
 * @ORM\Entity(repositoryClass="Ineat\FormGeneratorBundle\Entity\FormRepository")
 * @UniqueEntity("name")
 * @UniqueEntity("slug")
 */
class Form
{
    /**
     * @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="slug", type="string", length=255)
     */
    private $slug;

    /**
     * @var ArrayCollection
     *
     * @ORM\OneToMany(targetEntity="Widget", mappedBy="form")
     */
    private $widgets;


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

    // getters and setters
}

И один виджет:

/**
 * Widget
 *
 * @ORM\Table(name="widget_choices")
 * @ORM\Entity
 */
class WidgetChoices extends Widget
{
    /**
     * @var array
     *
     * @ORM\Column(type="array")
     */
    private $choices;

    // getters and setters
}

Всякий раз, когда я пытаюсь отобразить свою форму, у меня возникает следующая ошибка:

Ни свойство "WidgetText", ни метод "getWidgetText()", ни метод "isWidgetText()" не существуют в классе "Ineat\FormGeneratorBundle\Entity\Form"

Кажется, будто мои виджеты вообще не расширяли Widget. Мне нужен способ преобразовать мои виджеты в виджет или способ сообщить доктрине, что моя коллекция ArrayCollection может содержать все, что расширяет виджет.

Является ли это возможным?


person DevAntoine    schedule 16.05.2013    source источник
comment
В объекте WidgetText у вас есть свойство $text и общедоступный метод получения и установки, верно?   -  person cheesemacfly    schedule 16.05.2013
comment
Да, у меня есть соответствующие сеттер и геттер.   -  person DevAntoine    schedule 21.05.2013


Ответы (1)


Widget — это MappedSuperclass (без таблицы), а Form имеет к нему ключ 1-n. Поскольку каждый подкласс Widget будет жить в своей собственной таблице, это недопустимое отношение. Или, другими словами, MappedSuperclass может не иметь отношения n-1 (подумайте об этом больше как о декораторе).

Вы можете использовать общую парадигму внешнего ключа, чтобы сделать это так, как вы хотели, или использовать наследование одной таблицы для widget, что лучше для вашего случая (ref http://docs.doctrine-project.org/en/last/reference/inheritance-mapping.html#single-table-inheritance.)

table Widget(id, type)
table WidgetXY(id, X, Y)
table WidgetQR(id, Q, R)

Новый объект WidgetXY приведет к строке Widget(id=7, type=1) И строке WidgetXY(id=7, X, Y). Контроллер (доктрина) идентифицирует строку type=1, ссылающуюся на WidgetXY, используя карту дискриминатора на уровне базы данных, к которой вы просто присоединяетесь к правильной таблице, pkeys 1-1.

В доктрине вы должны установить тип наследования для соединения и определить свою карту дискриминатора в аннотациях (см. ссылку выше)

чт

person Community    schedule 16.05.2013
comment
Это единственное решение, которое у меня есть? Иметь таблицу, содержащую все о моем виджете, и несколько пустых столбцов — это не сексуально. - person DevAntoine; 17.05.2013
comment
Я принимаю это, потому что вы были правы насчет отношений, и мне нужно иметь сущность вместо mappedsuperclass для моих отношений, но моя форма все еще не может отображаться. - person DevAntoine; 23.05.2013