2010-07-17 14 views
2

我发现自己开始利用检查持久性来让我的模型“工作”。包含持久性检查似乎是方便和正确的。另一方面,它感觉有点阴暗,好像我过于谨慎或以小的方式打破ORM抽象。正在检查DataMapper(或其他ORM)模型是否存在代码异味?

一个例子可能是:

class Shipment 
    include DataMapper:Resource 

    belongs_to :address, :required => false 

    def shippable? 
    valid? && persisted? && !address.nil? && address.valid? && address.persisted? 
    end 
end 

在这种情况下,我需要告诉我,如果装运是可交付的方法。这是真实的,当它有效,保存到数据库,并有地址保存。

另一个例子可能是在回调中使用它来确定某些事情(价格重新计算)是否需要发生。

意见?这是不必要的,偏执的还是安全的,正确的?

回答

2

那么,如果真的是可能的,你来没有证实持久性或从数据库中重新加载执行点货,检查持久性似乎绝对必要的我。

但这是真的吗?你如何得到这个航运行动?我想这里有两个工作流程:

  1. 有一个您想要发货的订单。你点击“运送这个狗屎!”并获得ShipmentsController#new,输入您的数据。通过按“保存”,您的货件得到确认并保持有效。持续成功后(我假设shipment.save如果不是,则返回false),您可以直接继续进行运输操作(无论需要在那里完成任何操作)。如果shipment.save告诉你它没有持续,则#new视图会被再次渲染,并且尚未执行装运。所以这就是向导的想法-like“gate”的工作流程,只有在持久成功的情况下才允许您执行运输。

  2. 创建装运和装运货物完全是解耦。可以说一个人计划发货,另一个人执行发货。前者创建一个新的,有效的,持续运输。后者以易于计划的货物清单开始。这ShipmentsController#index使用Shipment.all直接从数据库加载货件。不需要检查persisted?然后在ShipmentsController#perform操作中。

好的。让我们把它变得更复杂: 现在假设我们处于方案2中,第一个人可以删除货物,而第二个人可以删除货物,而第二个人执行它。在不考虑这种情况下,天真的应用程序会在#perform完成后再次保存装运,并设置装运日期。这将意味着丢失了“删除”数据库异常已经发生。但是,不会使用状态机吗?因此,我们假设有过渡计划 - >删除计划 - >出货。如果家伙#1将状态设置为删除,而家伙#2正在执行发货,则状态机将抛出一个异常:“没有从删除转换到转移,亲爱的!“当试图更新状态

所以我不能真正弥补一个情况,明确检查持久性不是偏执狂,但如果你有一个地方它可能真的发生由于'不安全'的工作流程,你应该检查持久性。

相关问题