#php #forms #symfony #symfony4
#php #формы #symfony #symfony4
Вопрос:
Для проекта Symfony 4 нам нужно создать большую inpection
форму surfaces
с большим количеством полей. Мы ищем подход, как организовать структуру и взаимосвязи, а также учитывать скорость загрузки.
Я создал приведенный ниже пример базовой сущности, который по-прежнему легко хранить в одной таблице базы данных. Поля, приведенные ниже, представляют собой простые отношения или строковые поля, поэтому тип проверки будет простым.
class Inspection
{
/** @var string */
protected $projectName;
/** @var string */
protected $projectPlace;
/** @var User */
protected $inpector;
/** @var Customer */
protected $customer;
/** @var string */
protected $conclusion;
/** @var string */
protected $advice;
// Complex part
/** @var Collection */
protected $surfaces;
}
Теперь для сложной части.
Каждая проверка может содержать одну или несколько поверхностей (ArrayCollection).
Каждая поверхность состоит из разных полей, см. Ниже:
- Поверхность крыши (4 поля);
- тип текста
- тип выбора (одиночный)
- тип выбора (множественный)
- тип даты
- Утечка (3 поля);
- тип текста
- изображения (отношение, OneToMany)
- тип выбора (одиночный)
- Напряжение (3 поля);
- Наклон (3 поля);
- Загрязнение крыши (3 поля);
- Повреждение (5 полей);
- Балласт (3 поля);
- Карнизы (3 поля);
- Правильная работа (4 поля);
- Восстание расширения (5 полей);
- Дымоход (3 поля);
- Блок шунтирования (3 поля);
- … еще 9 ;
Мой вопрос, как настроить surfaces
и структурировать базу данных, должна ли каждая часть в surface иметь свою таблицу on, как показано ниже, с привязкой к проверке (это создало бы много таблиц, это плохо?):
- анализ таблицы
- table inpection_leakage
- table inpection_tension
- …
Я думал создать форму для встраивания коллекции, как показано ниже
class InspectionType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// ...
$builder->add('surfaces', CollectionType::class, [
'entry_type' => SurfaceType::class,
'entry_options' => ['label' => false],
]);
}
}
class SurfaceType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('leakage', LeakageTyoe::class);
$builder->add('tension', Tension::class);
$builder->add('slope', Slope::class);
...
}
}
Это путь 🙂 идти
Ответ №1:
Я бы предложил использовать карту дискриминатора / наследования для вашего объекта surfaces со single_table
стратегией. Это дает вам необходимую скорость и гибкость.
Комментарии:
1. Разве этот метод не создает много столбцов, когда у некоторых дочерних элементов есть свои собственные поля. Поскольку в каждой отдельной таблице (утечка, натяжение) не все одинаковые поля, см. Обновленное выше в коде
2. Может ли наследование таблицы классов, doctrine-project.org/projects/doctrine-orm/en/2.7/reference /… быть вариантом
3. Одна таблица действительно создает больше столбцов, но это нормально. При загрузке вашего
Leakage
объекта он будет использовать только поля, необходимые для утечки, и то же самое для напряжения. Наследование таблицы классов действительно также является опцией. Это в основном делает то же самое, что и наследование одной таблицы. Однако будьте осторожны: при большом количестве записей производительность может снизиться. Вот почему я предложил стратегию single_table.4. Создает ли наследование таблиц таблицу для каждой поверхности (
leakage
,tension
). А как насчет тех же полей (наследование). Должен ли я помещать эти поля только для его родительского и дочернего элементов, специфичных только для дочерних элементов? Я склоняюсь к наследованию таблиц классов, потому что оно описывает следующим образом: Эта стратегия сопоставления обеспечивает наибольшую гибкость во время разработки, поскольку изменения любого типа всегда ограничены выделенной таблицей этого типа. Возможно ли переключиться позже?. А как насчет изображений. Это новое отношение, поэтому новая таблица?5. Да, наследование таблиц классов (CTI) создает таблицу для каждой поверхности. С одной таблицей перекрывающиеся поля должны быть помещены в родительскую таблицу, с CTI вы помещаете ее в свой собственный класс. Просто попробуйте их оба и посмотрите, что лучше всего подходит для вас. Что касается перехода на одну таблицу позже: да, это возможно. Однако для этого вам нужно будет вручную написать миграции. Если вы хотите добавить изображения, я полагаю, вам нужен новый объект, поэтому будет создана новая таблица. Привязка его к вашим поверхностям не должна быть проблемой.