2016-01-31 22 views
0

我想處理,其中用戶輸入信息錯誤的情況,所以我有如下大致的路徑:如何在更新屬性之前添加錯誤?

class Thing < AR 
    before_validation :byebug_hook 
    def byebug_hook 
    byebug 
    end 
end 

thing = Thing.find x 
thing.errors.add(:foo, "bad foo") 
# Check byebug here, and errors added 
if thing.update_attributes(params) 
    DelayedJobThatDoesntLikeFoo.perform 
else 
    flash.now.errors = #... 
end 

byebug for byebug_hook> errors.messages #=> {} 

本來我想,也許該模型運行其自己的驗證和覆蓋的那些我補充說,但正如你可以看到,即使我添加前掛鉤錯誤丟失,我不知道是什麼原因造成的

實際解決方案 所以,@SteveTurczyn是正確的,錯誤需要發生在某些地方,在這種情況下,在我的控制器中調用的服務對象

我所做的更改是

class Thing < AR 
validate :includes_builder_added_errors 
    def builder_added_errors 
     @builder_added_errors ||= Hash.new { |hash, key| hash[key] = [] } 
    end 

    def includes_builder_added_errors 
    builder_added_errors.each {|k, v| errors.set(k, v) } 
    end 
end 

and in the builder object 
thing = Thing.find x 
# to my thinking this mirrors the `errors.add` syntax better 
thing.builder_added_errors[:foo].push("bad foo") if unshown_code_does_stuff? 
if thing.update_attributes(params) 
    DelayedJobThatDoesntLikeFoo.perform 
else 
    flash.now.errors = #... 
end 
+0

我想在你試圖讓你的代碼片斷簡潔你做了它難以遵循。無論哪種情況,我認爲你會在[這裏]找到你的問題的答案(http://guides.rubyonrails.org/active_record_validations.html#performing-custom-validations) – Iwnnay

回答

1

update_attributes將驗證模型......這包括清理現有的所有錯誤,然後運行任何before_validation回調。這就是爲什麼在

pont沒有任何錯誤如果你想添加一個錯誤條件的「正常」驗證錯誤,你最好將它作爲模型中的自定義驗證方法。

class Thing < ActiveRecord::Base 
    validate :add_foo_error 

    def add_foo_error 
    errors.add(:foo, "bad foo") 
    end 
end 

如果你想只發生在特定的控制器或條件的一些驗證,你可以做,在模型上設置一個attr_accessor值,你直接運行驗證之前設置的值(?:有效)或間接地(:update,:save)。

class Thing < ActiveRecord::Base 
    attr_accessor :check_foo 
    validate :add_foo_error 

    def add_foo_error 
    errors.add(:foo, "bad foo") if check_foo 
    end 
end 

在控制器...

thing = Thing.find x 
thing.check_foo = true 
if thing.update_attributes(params) 
    DelayedJobThatDoesntLikeFoo.perform 
else 
    flash.now.errors = #... 
end 
相關問題