0

Order我和Item模型之间有非常紧密的关系。

Order hasMany Item
Item belongsTo Order
Item hasMany ChildItem

ChildItem is alias for Item (it's a recursive model)

订单模型有一个特殊的Order::prepare()功能。它在所有附加的行为上触发一个Order.prepare事件,这些行为控制、验证和修改项目数据,例如运输、项目/订单重量、数量、折扣等。验证和暂存数据以进行保存操作。它还设置Order.total, Order.weight, Order.status, ...字段。

任何行为也可以根据其限制(库存限制、重量限制、增值税、任何东西)停止准备工作。

何时Item添加到现有的Order

  1. 从数据库中检索订单及其所有现有项目
  2. 新的 Item 数据被添加到 Items 数组中
  3. 订单已准备好(所有行为运行,Item.subtotals Order.total,,重量等都被重新计算......)
  4. 如果准备成功,所有新的(和修改的)订单和项目数据都将使用 Order.saveAssociated 保存。

在仔细考虑了多种方法后,我选择了第三种方法,但我卡住了:

beforeSave 回调

此回调将确保这些回调和计算在每个项目上运行,但它使检索相关的订单数据和项目以及运行回调变得更加困难。也很难确定数据是否已经准备好,递归也是一个问题。更难返回准备好的数据而不是保存它。

扩展Model::save方法

递归也是一个问题,没有保存就无法返回准备好的数据,我通常避免扩展 save()。

解耦准备和保存过程 通过使用自定义模型方法和回调(例如 Order::prepare 和 Order::commit),为订单数据操作创建一个特殊的工作流。行为在非标准事件(beforePrepare、beforeCommit 等)上运行,并且 Model::save() 保持不变。

我很乐意提供更多细节,但它确实是一个庞大的模型,这将是一个很长的问题,我已经尽可能地总结了。任何有关正确方法的想法或示例将不胜感激。

4

2 回答 2

1

我不确定你的系统有多复杂 - 但你为什么不创建一个 OrderPrepare 类(我通常让这个类扩展 Object 而不是 AppModel 或 Order,并将它放在 Model 文件夹中,或者我把它放在 Lib 文件夹中),传入Order 对象,然后您可以在该类中执行您想要的任何逻辑?

于 2013-08-29T12:21:46.677 回答
0

我已经设法通过这项努力进行战斗,我正在发布结果和我当前的解决方案。我不认为这完全是传统的工作流程,但它做得很好。

我创建了BaseOrderBaseItem类,它们扩展了 AppModel 并打算用您自己的类进行扩展。

我创建了BaseOrder::fetch(),BaseOrder::stage()BaseOrder::commit()方法,它们是用于工作的核心操作。它们都在回调之前之后触发,回调是自定义事件名称,使用自定义 OrderEvent (扩展 CakeEvent)对象发布。

BaseOrder::fetch()

这用于从数据库中获取订单的当前状态。

  • 从其相关的 BaseItem 类和行为中收集所有关联要求。这允许每个行为即时进行自定义关联(例如 Couponed 行为附加Order hasMany Coupon)、修改query=>contain数据,以确保 Order::fetch() 为工作流检索正确的数据。
  • 运行生成的查询
  • 运行 AfterFetch 回调,它允许任何 Behavior 或 OrderItem 实例附加或调整所需的其他数据。

BaseOrder::stage()

接收任何类型的 Order 相关数据作为参数,执行 a Order::fetch(),应用和修改数据并运行所有行为和 OrderItem以及beforeStage回调。stageafterStage

该方法有望返回订单的真实状态,并解决所有细节,例如产品数据、财务细节、折扣、行为附加数据等。

BaseOrder::commit()

采用分段订单数组,验证财务,将数据提交到数据库。

此外,BaseItemandBaseOrder都有一个afterSave回调,它会触发重新计算相关订单记录的财务,以防任何数据手动保存到数据库中。

这样,我可以轻松地为所有花里胡哨的东西准备/提交订单,或者我可以直接更新订单/项目数据并保持财务数据的完整性。

我正在考虑将事物的计算方面移至 MySQL 存储过程,该过程将在每次保存后自动运行,但它会将微调控制从应用程序中移除(如舍入错误、默认税率等)

我期待有人去不,不,不,你做错了,并用一个更好的主意启发我,因为所有这些都感觉很脏。

我遇到的最大“问题”是获取所有相关的 BaseItem 扩展模型并遍历数据数组以“捞出”它们进行计算。这允许我拥有不同的模型(如 ProductItem、ShippingItem)以及它们之间的不同关系,但会产生轻微的开销。

于 2013-09-01T17:15:29.407 回答