剛剛開始看的DataMapper Ruby的ORM我碰到的,混淆我沒有盡頭的一個問題。古怪的行爲在紅寶石DataMapper的節能實例時
保存DataMapper實例時的默認行爲(通過DataMapper :: Resource.save)據我所知,會以靜默方式失敗,從save方法返回false並收集錯誤集合中的任何錯誤。迄今爲止,這很好,這是按預期工作的。我看到的問題是與自然的主鍵,在這裏設置重複者將拋出一個異常,而不是默默地從保存方法返回假,公然無視raise_on_save_failure的當前設置。考慮下面的片段;
require 'data_mapper'
class Thing
include DataMapper::Resource
property :name , String, :key=> true
property :description, String, length: 2..5
end
DataMapper.setup :default, "sqlite:memory"
DataMapper.finalize
DataMapper.auto_migrate!
#Create a thing and have it properly silently fail saving
t1=Thing.new(:name=>"n1",:description=>"verylongdescription")
t1.save #ok
puts("t1 is saved:"+t1.saved?.to_s)
t1.errors.each do |e|
puts e
end
#Create two things with the same key, and fail miserably in silently failing the second save...
t1=Thing.new(:name=>"n1",:description=>"ok")
t2=Thing.new(:name=>"n1",:description=>"ok")
t1.save #ok
t2.save #not ok, raises Exception event though it shouldn't?
puts("t2 is saved:"+t1.saved?.to_s)
t2.errors.each do |e|
puts e
end
首先保存在一個實例失敗的驗證規則:描述財產的行爲與預期。第三個保存具有重複鍵的實例,但是不會,因爲它會引發一個執行,而不是很好地返回false。
這是爲什麼?顯然可以解決,但它並不是很清楚。那是無聲的行爲將僅適用於驗證錯誤在DataMapper的層的情況下,從底層數據存儲的任何硬錯誤將被傳播作爲例外來電?
謝謝!
驗證捕獲最終用戶錯誤,重複鍵到數據庫是程序員錯誤。如果除以零或'save'序列中沒有處理'nil'正常,你會得到同樣的原因異常。 – 2012-02-08 20:10:24
是的,這是有區別的,現在我在DataMapper中更多地瞭解驗證和靜默/非靜默行爲的目的。然後我猜測在上面的例子中,如果你添加了一個獨特的驗證, – osmbergs 2012-02-09 19:17:10
不幸的是,唯一性驗證是不夠的,因爲它受到競爭條件的限制,所以您在數據庫中也需要一個唯一的約束條件,但是當競爭條件發生時您會得到一個異常。 – 2012-02-09 21:36:52