2017-07-24 69 views
0

如何解決after_save回調中生成的錯誤,然後最終將其顯示給用戶?在我的模型代碼看起來是這樣的:Rails:向after_save回調中產生的用戶顯示錯誤

Class MyModel 
    after_save :call_other_class_responsible_for_parsing 

    def call_other_class_responsible_for_parsing 
    # this method is used by multiple models 
    ModelTwo.parse_css 
    end 
end 

在我的控制,我現在將用戶重定向的其他地方,如果升級成功,但是,我認爲更新是成功的,如果它通過了所有現有的驗證的回調中沒有錯誤(來自Less :: Parser)。

編輯:

我混淆了我的想法在我原來的問題。 MyModel從相應的控制器中獲取,然後從模型中運行after_save回調。在call_other_class_responsible_for_parsing裏面,有一個對另一個模型的調用,比如ModelTwo,它可以進行Less解析。我一直在使用這樣的代碼嘗試:

def self.parse_css 
    @my_model = MyModel.find(1) 
    css_to_compile = Less::Parser.new.parse(css).to_css 
    rescue Less::Error => error 
     @my_model.errors[:base] << "Error message"  
     false 
    end 
    end 

false並不妨礙交易得手,因此重定向發生。

+0

您是否將您的MyModel對象保存在多個位置?如果沒有,您可以在成功執行'my_model.save'後調用'my_method',而不是使用回調。 – Gerry

回答

0

你可以使用事務:

def create 
    MyModel.transaction do 
    @my_model.save 
    @my_model.my_method 
    end 
    rescue ActiveRecord::RecordInvalid => exception 
    # rescue active record exception here 
    rescue Less::Error => exception 
    # rescue less error here 
end 

這消除對回調的需要。

我希望這有助於!

0

回調鏈隱式包裝在一個事務中。當回調返回false或引發異常時,整個事務回滾並保存失敗。

就你而言,你解析了一些CSS,所以我不確定after_save是否適合這個。 我建議你試一試。考慮以下幾點:

class MyModel < ActiveRecord::Base 
    validate :valid_css 

    private 

    def parsed_css 
    @parsed_css ||= Less::Parser.new.parse(css).to_css 
    end 

    def valid_css 
    parsed_css 
    rescue Less::Error => error 
    errors.add(:css, "Cannot parse CSS: #{error}") 
    end 
end 

這將解析CSS 之前保存對象,如果它是無效的添加錯誤。此外,#to_css的結果將被存儲,以便您不需要重新計算它。 這是我推薦的方法

如果你想堅持after_save那麼你應該提出異常中止交易。根據你的情況,它只是關於不救Less::Error

class MyModel < ActiveRecord::Base 
    after_save :compile_css 

    private 

    def compile_css 
    css_to_compile = Less::Parser.new.parse(css).to_css 
    end 
end 

如果您無法決定要使用的方法,然後在下方留下一個問題,我會幫助你。

+0

謝謝,我試過errors.add,並且沒有運氣返回false。我也編輯了這個問題。 – mycellius

+0

@mycellius,你是對的。我很困惑。爲了從after_ *回調中止事務,您需要引發異常。我更新了我的答案以反映這一點。另外,爲什麼不使用'驗證'呢? –

+0

我試過你的方法沒有運氣。我在保存之前不能使用驗證的原因是因爲解析器使用綁定來評估MyModels屬性,因此它將已保存的值注入到由Less分析的模板中。這裏是我所遵循的教程:[鏈接](https://matteodepalo.github.io/blog/2013/02/01/refactor-replace-method-with-method-object/) – mycellius