2012-04-15 60 views
1

這裏很基本的問題,我需要在我的Category模型上編寫一個before過濾器,以確保深度永遠不會超過2個。這是迄今爲止我所擁有的。如何在創建之前驗證模型屬性

應用程序/模型/ category.rb

before_create :check_depth 
    def check_depth 
    self.depth = 1 if depth > 2 
    end 

我需要它,而不是設置深度爲1,只返回一個錯誤消息,但我甚至無法得到這個當前的設置工作,我得到錯誤

undefined method `>' for nil:NilClass 

所以,而不是設置深度爲一個像我試圖做我將如何發送錯誤呢?任何幫助獲取當前函數的信息用途?在此先感謝

回答

5

有多種方法可以做到這一點。

你最簡單的解決方案:

def check_depth 
    self.errors.add(:depth, "Issue with depth") if self.value > 2 # this does not support I18n 
end 

最乾淨的使用模型驗證(您category.rb的頂部,只需添加):

validates :depth, :inclusion => { :in => [0,1,2] }, :on => :create 

如果您的驗證邏輯得到更復雜的,使用自定義驗證程序:

# lib/validators/depth_validator.rb (you might need to create the directory) 
class DepthValidator < ActiveModel::EachValidator 
    def validate_each(record, attribute, value) 
    record.errors.add(attribute, "Issue with #{attribute}") if value > 2 # this could evene support I18n 
    end 
end 

在使用此驗證程序之前,編輯加載它,例如在初始化

# config/initializers/require_custom_validators.rb 
require File.join('validators/depth_validator') 

您需要重新啓動您的軌道服務器更改後(和您在您的驗證作出更改之後)。

現在,在您的產品類別型號:

validates :depth, :depth => true, :on => :create # the :on => :create is optional 

問題將在@category.save提高,所以你可以設置你的閃光的通知,像這樣:

if @category.save 
    # success 
else 
    # set flash information 
end 
+0

哎呀,如果驗證邏輯不太複雜,你甚至不需要自定義過濾器 - 將更新我的答案。 – emrass 2012-04-15 07:50:10

+0

謝謝你提供的所有信息,我用它提供了最直接的答案,並且確實使用了I18n,所以我將使用自定義驗證器。非常感謝你的努力。 – ruevaughn 2012-04-15 21:39:56

+0

太棒了! I18n也將採用上述「最乾淨」的解決方案(選項2)。您只需在您的語言環境中爲[en | de | ...]。errors.messages.inclusion進行翻譯 - 或者在此處使用示例語言環境之一https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale作爲基礎。對於自定義驗證器,而不是錯誤文本「mytext ...」放置一個符號,如:depth_not_in_range,並在[locale] .collaboration.errors.models.category.attributs.depth.depth_not_in_range中有翻譯 – emrass 2012-04-15 22:09:35

1

您現在得到的錯誤是因爲depth是零。我相信你想使用self.depth,如:

def check_depth 
    self.depth = 1 if self.depth > 2 
end 

我真的不知道你是什麼意思發送一個錯誤...發送一個錯誤的位置呢?你在一個模型...

+0

我想我是想象發送一個錯誤,如:notice或something,但我想你可以在模型中不會這樣做。這是我應該在控制器中進行的檢查,而不是模型呢? – ruevaughn 2012-04-15 05:46:13

+0

我相信如此...但是,您可以設置對象的屬性,如over_depth = true ... – Nobita 2012-04-15 05:48:04

+0

真的,我可以嘗試,我會在我的控制器中創建一個before_filter,並有輔助方法來執行檢查嗎?或者在我的控制器中怎麼做呢? – ruevaughn 2012-04-15 05:50:40

2

我會建議簡單明瞭的方法:

# in your Comment.rb 
validates_inclusion_of :depth, in: 0..2, message: "should be in the range of 0..2" 
+0

這似乎適用於我以及。謝謝你的幫助 – ruevaughn 2012-04-15 21:41:08

相關問題