强制保存!操作失败
我有一个ImagesController
,它启动了一个非平凡的保存操作。这里的高级背景:强制保存!操作失败
我有几种不同的物理文件类型来处理我的应用程序。这些每个belongs_to
a Binary
。当然,可以创建文件,并且此过程涉及将物理文件上传到临时位置,可能验证物理文件(对于大小,类型或其他),然后假设没有问题将文件移动到永久位置然后在适当的表格中创建数据库记录(为了我的问题,我们使用images
和binaries
)。
Image
属于Binary
并且有BinaryObserver
观察Image
类。在那个观察者类中,有一个before_create()
方法,它告诉Binary
类上传图像的物理文件并在数据库中保存相关记录(包括名称,路径,URI信息等)。
观察者类方法所做的一件事是测试原始模型中的回调方法,在这种情况下为Image
。如果方法存在并因任何原因返回false,那么我需要保存操作失败。我无法弄清楚如何做到这一点。
在我的控制器的create()
方法,我有:
if @image.save!
flash[:notice] = "Successfully created image."
redirect_to @image
else
flash[:notice] = "Upload failed."
render :action => 'new'
end
我无法弄清楚如何触发else
块。在我BinaryObserver
类,我有:
def before_create(model)
binary = Binary.new.upload(model.upload)
if !model.respond_to?('before_file_save') || model.before_file_save()
binary = binary.store()
model.binary_id = binary.id
model.active = 1
return true
else
# binary.destroy()
File.delete(File.join(Rails.root, binary.path))
return false
end
end
目前,Image.before_file_save()
仅返回false。物理文件被删除,但保存并未失败,并且我的控制器显示一条错误消息,表明其show()
方法找不到图像(这是合理的,因为图像未保存且物理文件已被删除)。
如果观察者类'before_create()
方法返回false,我该如何强制保存操作失败?
谢谢。
这是我的理解是,如果操作失败,在Model方法上使用bang(!)语法将引发异常。显然,保存并不失败,但Observer需要让你的控制器知道出了问题。我会按照这样做的相同AR的方式,有例外:
begin
@image.save!
flash[:notice] = "Successfully created image."
redirect_to @image
rescue YourObserverException => e
flash[:notice] = "Upload failed."
render :action => 'new'
end
这意味着观察者没有返回true,但如果上传失败确实引起YourObserverException
(你在哪里returning false
)。
您的观察者IS仍在基本上位于顶部的ActiveRecord Transaction内部运行。所以DB明智的你应该仍然有诚信。但是为了将这些信息传递给顶端,我会在返回false之前在对象中设置一个实例变量。由于控制器仍然在Observer的同一个对象上运行,因此可以使用相同的信息。
...在你的观察 model.is_valid =假#or_something_went_wrong =真等 返回false
然后,只需对相应的操作在您的控制器。
我更喜欢你的方法 - 更清洁。 – 2009-08-19 23:44:52
谢谢,这个工作很好,一旦我想出了如何在Ruby中引发异常。我通常是异常处理的重要用户,但我想我只是假定返回false会使保存无效。科迪上面说的是合理的,但是模型完整性仍然完好无损,因为这是在保存之前发生的。 – 2009-08-20 00:15:42