symfony - 在 Symfony 4 中创建单例实体的最佳方法是什么?
问题描述
我想创建一个设置页面,其中只有一个表单。如果提交了表单,它只会更新设置实体,但不会创建另一个。目前,我实现了这样的目标:
/**
* @param SettingsRepository $settingsRepository
* @return Settings
*/
public function getEntity(SettingsRepository $settingsRepository): Settings
{
$settings = $settingsRepository->find(1);
if($settings == null)
{
$settings = new Settings();
}
return $settings;
}
在 SettingsController 我调用getEntity()
返回新设置实体(如果尚未设置设置)或已经存在的设置实体(如果设置至少设置一次)的方法。
但是我的解决方案非常丑陋,并且它具有硬编码的实体 ID“1”,所以我正在寻找更好的解决方案。
设置控制器:
public function index(
Request $request,
SettingsRepository $settingsRepository,
FlashBagInterface $flashBag,
TranslatorInterface $translator,
SettingsService $settingsService
): Response
{
// getEntity() method above
$settings = $settingsService->getEntity($settingsRepository);
$settingsForm = $this->createForm(SettingsType::class, $settings);
$settingsForm->handleRequest($request);
if ($settingsForm->isSubmitted() && $settingsForm->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($settings);
$em->flush();
return $this->redirectToRoute('app_admin_settings_index');
}
return $this->render(
'admin/settings/index.html.twig',
[
'settings_form' => $settingsForm->createView(),
]
);
}
解决方案
你可以在这里使用Doctrine Embeddables。
严格来说,设置不应映射到实体,因为它们不可识别,也不应如此。当然,这是一个有争议的问题。实际上,设置对象更像是一个值对象而不是一个实体。阅读此处了解更多信息。
因此,在这种情况下,比拥有一对一关系和所有那些模糊的情况更好,您可能会使用一个名为 settings 的简单值对象,它将作为 Doctrine Embeddable 映射到数据库。
您可以通过仅在工厂方法中创建它的实例、使构造函数私有、防止克隆等来使该对象成为单例。通常,仅使其不可变就足够了,也就是说,没有任何行为可以改变它的状态。如果你需要改变它,那么负责它的方法应该创建它的一个新实例。
你可以有一个这样的方法,并且在你新建一个实体时Settings::createFromArray()
调用另一个方法:总是默认配置。Settings::createDefaults()
然后,您的实体上的 setSettings 方法仅接收一个设置对象作为参数。
如果您不喜欢不可变性,您还可以为 Settings 对象创建 setter 方法。
推荐阅读
- angularjs - 使用 nodejs 8、angularjs、ionic3、cordova8 更新 cordova-android 6 到 9、cordova-ios 5 到 6
- git - 这种情况下最好的分支策略是什么?
- javascript - 有没有办法在 TypeScript 类中返回 express 实例?
- gremlin - 获取更多关于 Gremlin 遍历的数据而不仅仅是节点 ID?
- azure - 如何在没有/使用简单身份验证的情况下显示 Azure 监控仪表板?
- r - 如何将预测列表转换为R中的规范化表
- fft - 如何使用傅里叶变换计算动量矩阵元素?
- python-3.x - yt_search 在控制台中打印。如何删除它?
- pine-script - 我将如何在给定范围内仅使用牛市蜡烛进行一些计算?
- wordpress - WordPress elementor 插件中的错误 500