以下是我正在嘗試執行的操作;我認爲這是一個普遍的問題,但不知何故我找不到任何相關的主題...Rails 3:處理ActiveRecord模型中數據庫適配器的異常
我有一個範圍的唯一性約束模型。我已經決定在遷移上的表定義唯一索引,像這樣做:
class CreateLossRatios < ActiveRecord::Migration
def up
...
add_index :loss_ratios, [ :tool_id, :ends_at ], :unique => true
end
def down
...
end
end
這讓試圖保存記錄違反指數獨特的ActiveRecord時拋出異常。現在我想讓它看起來是一個驗證錯誤。我認爲最好的方法是在LossRatio模型中捕獲ActiveRecord :: RecordNotUnique權限,並用有意義的消息填充錯誤散列。我這樣做了:
class LossRatio < ActiveRecord::Base
belongs_to :tool
validates :rate, :ends_at, :tool, :presence => true
validates_numericality_of :rate
validates_inclusion_of :rate, :in => (0..1)
%w{ create save }.each do |name|
%W{ #{name} #{name}! }.each do |method|
define_method(method) do |*args|
begin
super(*args)
rescue ActiveRecord::RecordNotUnique => ex
self.errors.add(:ends_at, I18n.t('activerecord.errors.models.loss_ratio.attributes.ends_at.not_unique'))
end
end
end
end
end
這工作,但似乎有點麻煩。我知道我在這裏做假設(即如果我添加另一個數據庫級別唯一性約束等會發生什麼情況),但我沒有看到解決方法。處理這種情況時是否有更優雅的解決方案/最佳做法? 一種選擇,我能想到的是使用rescue_from,但我不想這樣做,因爲
- 我不認爲這個邏輯控制器中的屬於,我希望把它透明的應用程序邏輯
- 最有可能不會有關聯的控制器(這些對象將僅作爲通過另一個模型的關聯而創建),這使得從我的角度來看它更加錯誤。
有沒有辦法讓這個模型從任何實例方法拋出的異常救援?我試過使用一個類級別的救援條款,但它沒有捕獲任何東西。
另一個問題是,我是否仍然使用AR範圍驗證的ends_at。即使RecordNotUnique處理完畢,對象仍會認爲自己有效,並在嘗試保存失敗後設置其時間戳。它可以導致任何不需要的副作用嗎?
除了我下面的評論,你不應該'保存'從不提出任何例外。它只是返回true或false。 – 2012-04-11 06:18:28
具體來說,在這種情況下,當通過DB約束繞過ActiveRecord進行驗證時,RecordNotUnique也由non-bang方法引發。 – HargrimmTheBleak 2012-05-04 08:12:04