考虑以下情况
我们有一个简单的数据库,涉及两个实体:user
和category
对于我们的假设,假设user
只能有一种category
,而category
可以与 n users
相关联。
现在,考虑一个网页,其中user
- 说ROLE_ADMINISTRATOR
- 可以编辑用户表并将其关联到另一个category
。
据我所知(并且我一般都是symfony的新手)如果我同时使用Doctrine和symfony2,使用 - 比方说 - 注释方法,我将有两个实体(php类)。
嵌入表格
我将创建一个表单,显示user
,然后显示 - 并保持,当然! - 他的category
我选择“遵循”嵌入式“战略。
说完已创建实体后,我必须为category
创建一个表单(假设在formBuilder
中我只会添加id
的{{1}}属性)。
之后我必须向UserType类的category
添加前一个表单,并且使用“某种魔法”表单将呈现(在适当的操作之后)作为魔法,就像魔法一样,当我发布它时(并绑定,等等)返回所有信息将持久存储到数据库
数据变形金刚
又名将表单的输入转换为对象,反之亦然
通过这种方式,我将不得不定义一个 - 让我们说 - formBuilder
进入他的构建器,将添加一个将执行这些转换的类(服务?)。
现在我们定义数据转换器本身将实现CategorySelectorType
(用他的方法等等)
下一步是将该实体注册到服务中,并将DataTransofmerInterface
添加到将使用此服务的表单中。
因此,我不理解这两种方法之间存在“强烈”差异,但服务的“可重用性”。有人可以给我一个不同的观点,并解释我的差异,如果有的话?
答案 0 :(得分:2)
数据转换器不会替换嵌入的表单,而是可以很好地增强表单和包装数据转换。
cookbook page about Data Transformers上的第一句话总结得很好:
您经常会发现需要转换用户输入的数据 在你的程序中使用其他东西。
在上面的示例中,您可以添加类别下拉列表,以便管理员可以为给定用户选择一个。这将使用嵌入式表单完成。由于类别字段是现有类别的ID,因此无需转换数据。
出于某种原因,您现在希望管理员能够输入该类别的自由文本。现在,您需要将文本转换为相关对象。也许您希望他能够添加新的或使用此文本字段选择当前类别。两者都可以通过使用数据转换器来获取文本并搜索类别。根据您的需要,不能创建和返回现有类别。
另一个用例是用户输入需要在存储之前以某种方式修改的数据。假设用户输入街道,门牌号码和城市,但您想要存储坐标。
在这两种情况下,将表单嵌入另一个表单并不重要!
你能在你的控制器中做到吗?当然。在控制器中做这些事情是个好主意吗?可能不是,因为你很难进行测试(在变压器中进行测试时可以很好地对转换进行单元测试)或重复使用。
<强>更新强>
当然可以将转换代码放在其他位置。用户对象本身不是一个好地方,因为模型不应该知道实体管理器,这是进行转换所需要的。 用户类型是可能的,但这意味着它与实体管理器绑定。
这一切都构成了Separation of concerns这个非常强大的概念,它指出一个类应该只做一件事来使它可维护,可恢复,可测试等等。如果你遵循这个概念,那么应该清楚的是,数据转换本身就是一个问题,应该如此强化。如果您不在乎,则可能不需要转换功能。