CakePHP 保存非常深的关联模型
Posted
技术标签:
【中文标题】CakePHP 保存非常深的关联模型【英文标题】:CakePHP Saving Very Deep Associated Models 【发布时间】:2014-07-11 02:10:15 【问题描述】:我有一个使用党分析模式来简化关联的数据库(因为它必须存储有关人员和组织的信息,两者都有共同的属性)。因此,我的相关模型可以变得相当深入。我的问题是保存数据的最佳方法是什么?以保存员工为例,Employee 表不直接连接到 Party 表,但是如果我将模型嵌套在这样的数组中:
array(
'Party' => array(
'Email' => array(...),
'Address' => array(
'Country' => array(...),
'Location' => array(
'State' => array(...)
)
),
'PhoneNumber' => array(...),
'Person' => array(
'Language' => array(...),
'Skill' => array(...),
'Employee' => array(
'WorkHistory' => array(...),
'Qualification' => array(...)
)
)
)
)
我可以使用 saveAll,它会保存所有内容。这意味着在我的表单上,我有诸如 Party.Person.Employee.start_time 之类的字段名称。然而,有人告诉我这样做并没有真正遵循 Cakephp 的约定。另一种选择是让我的数组像这样:
array(
'Party' => array(...)
'Email' => array(...),
'Address' => array(...),
'Country' => array(...),
'Location' => array(...),
'PhoneNumber' => array(...),
'Person' => array(...),
'Language' => array(...),
'Skill' => array(...),
'Employee' => array(...),
'WorkHistory' => array(...),
'Qualification' => array(...)
)
但是,如果我对此调用 saveAll,则不会保存所有内容,因为某些表/模型没有直接连接到 Party。据我所知,保存这种结构的唯一方法是使用事务。
所以我想知道 CakePHP 专家认为解决需要保存非常深的关联模型的情况的最佳方法是什么?
编辑:
根据我收到的响应可以收集到的信息,对于您调用 saveAll 的模型,与它直接关联的其他模型不需要嵌套在该模型数组中。但是,如果您还想保存与它没有直接关联的模型,那么您需要将这些模型嵌套在与您调用 saveAll 的模型直接关联的模型中。抱歉,我知道这很令人困惑,所以这里是我根据这些信息修改后的数组结构:
array(
'Party' => array(...),
'Email' => array(...),
'Address' => array(
'Country' => 'attribute',
'Location' => 'attribute',
'State' => 'attribute'
),
'PhoneNumber' => array(...),
'Person' => array(
'Language' => array(...),
'Skill' => array(...),
'Employee' => array(
'WorkHistory' => array(...),
'Qualification' => array(...)
)
)
)
Person 直接与 Party 关联,因此不需要嵌套在 Party 中。但是 Employee(Person 的一种)与 Party 没有直接关联,因此在 Party 上调用 saveAll 时要保存 Employee 数据,需要嵌套在 Person 中,因为 Person 模型直接与 Party 关联。 (仅供参考:Party hasOne Person 和 Person hasOne Employee。这是我能想到的在我的数据库中构建继承的最佳方式)。通过以这种方式构建它,应用程序既符合 CakePHP 标准,又能以最小的努力保存数据。
【问题讨论】:
这个人有没有给你解释为什么不使用第一种方式?如果它有效,我会使用它。 这是我询问的关于“可包含”的问题的链接,我试图在我的视图中以表单的方式格式化数组:***.com/questions/24604104/… 发表的评论是“为什么如果你想一开始就违反 CakePHP 约定,那只会造成麻烦……”。但没有解释。然而,响应者并没有真正了解我为什么要这样构建我的数组。所以我想我应该检查一下是否可以,或者是否有理由不这样做。 【参考方案1】:好吧,解释就在那里,它只是 CakePHP 约定,我们都知道不遵守约定会发生什么,对吧?
正如我所说,遵循约定有助于 CakePHP 自动将所有内容粘合在一起,并且使用您问题中显示的格式需要手动重组您的 Model::find()
调用接收到的数据。
因此,虽然您的问题中显示的结构可能适用于保存(至少目前是这样),但它至少会为您带来一些实际上不必要的额外工作。
我承认我本来可以更清楚一点,因为你似乎误解了我。我不想说数组应该完全是平的,只是Person
条目放错了,所以我只提到了那个。
当然,最终这一切都取决于关联的类型,链接文档中有所有示例:Cookbook > Models > Saving Your Data
一般情况下,只要没有任何 HABTM 关联,您就可以使用 saveMany()
或 saveAssociated()
尽可能多地保存。
您可以通过参考 Model::find()
返回的结构开始,确保您保存在主模型上(在本例中为 Party
),并取决于使用的关联/记录数
save()
(单条记录,无关联(HABTM
除外))
saveAll()
(saveMany
和 saveAssociated
的包装)
saveMany()
(多个主模型记录,可能的关联(需要使用deep
选项))
或saveAssociated()
(单个主模型记录,包括关联(可能需要使用deep
选项)
但是这可能不适用于所有情况,如前所述,您可能会遇到HABTM
关联的问题,具体取决于您是否要创建新记录,您可能需要单独保存它们,但这并不是真的解释每一种可能的情况的地方,尤其是因为基本知识已经包含在 Cookbook 中。
我建议您学习文档,遵守约定,边尝试边学习,并查看核心源代码和测试,我们每个人都是这样学习的。当您对尚未涵盖的特定情况有疑问时,只需创建一个新问题
【讨论】:
在食谱中它说“为了保存一条记录及其相关记录,hasMany 有两个以上的深度关联,数据数组应该如下......”。然后它继续给出一个数组结构的例子,它看起来像我为这个问题提供的第一个例子。因此,基于此,虽然我的关联是 hasOne,但我相信我通过提交该格式的数组来遵循约定。我发现如果我不这样做,它就不会保存员工数据。再次感谢您抽出宝贵时间帮助我完成此过程:) @user3394751 不,它看起来不像你的例子,它看起来像我建议的那样,Cart
键 not 嵌套像你的 Person
key ;) 同样,这只是 Person
键,其他的都正确嵌套了!
好的,我想我明白了。我已经修改了我的问题以反映新的数组结构。在食谱示例中,“Cart”没有嵌套在“Person”中,但是“CartItem”嵌套在“Cart”中。基于该逻辑,如果模型直接连接到您调用 saveAll 的模型,则无需嵌套它,但如果不是,则需要将其嵌套在模型中。它是否正确?你能用新的数组结构看看我修改后的问题,然后告诉我你觉得还可以吗?谢谢!
@user3394751 我不了解您示例中的所有关系,但是从您所描述的内容来看,到目前为止看起来还不错,是的,您所说的是正确的,直接的-不要嵌套,间接 - 嵌套,除了 HABTM
关联,它们有点特别:)
非常感谢,非常感谢您对此提供的所有帮助。以上是关于CakePHP 保存非常深的关联模型的主要内容,如果未能解决你的问题,请参考以下文章