2008-12-11 99 views
20

我有一個Rails應用程序,可以讓用戶通過填寫​​一個廣泛的窗體來構建數據庫查詢。我想知道在Rails中檢查表單參數的最佳做法。以前,我有我的results方法(一個表單提交)執行以下操作:Rails窗體驗證

if params[:name] && !params[:name].blank? 
    @name = params[:name] 
else 
    flash[:error] = 'You must give a name' 
    redirect_to :action => 'index' 
    return 
end 

但對於一些表單字段,看到這個重複每一個有煩人。我不能只是堅持他們都在一些循環來檢查每個字段,因爲字段的設置有所不同:

  • 一個鍵:params[:name]
  • 鍵和子鍵:params[:image][:font_size]
  • 只希望如果其他字段設置

等,這也是重複的,因爲我是爲每個缺少/無效參數設置flash[:error],並重定向到爲每一個相同的URL某種形式的字段填寫。我切換到使用before_filter,檢查所有必要的表單參數,只有在一切正常時才返回true。然後我results方法繼續和變量只是分配平展,沒有檢查涉及:

@name = params[:name] 

在我validate_form的方法,我有如下所示的代碼段:

if (
    params[:analysis_type][:to_s] == 'development' || 
    params[:results_to_generate].include?('graph') 
) 
    {:graph_type => :to_s, :graph_width => :to_s, 
    :theme => :to_s}.each do |key, sub_key| 
    unless params[key] && params[key][sub_key] 
     flash[:error] = "Cannot leave '#{Inflector.humanize(key)}' blank" 
     redirect_to(url) 
     return false 
    end 
    end 
end 

我只是想知道我是否以最好的方式解決這個問題,或者如果我在參數驗證方面失去了一些顯而易見的東西。我擔心這仍然不是最有效的技術,因爲我有幾個塊,我將值賦給flash[:error],然後重定向到相同的URL,然後返回false。

編輯澄清:我之所以沒有在模型(一個或多個)這個驗證目前有兩個原因:

  • 我並不想從用戶那裏收集數據,以便創建或更新數據庫中的一行。用戶提交的數據在註銷後都不會保存。當它們提交它來搜索數據庫並生成一些東西時,它們都是正確的。
  • 查詢表單接收與幾個模型有關的數據,並且它接收其他與模型無關的數據。例如。上面顯示的圖形類型和主題不連接到任何模型,它們只是傳達有關用戶如何顯示其結果的信息。

編輯顯示改進的技術:我使用的應用程序特定的例外,現在,多虧了Jamis巴克的Raising the Right Exception article。例如:

def results 
    if params[:name] && !params[:name].blank? 
    @name = params[:name] 
    else 
    raise MyApp::MissingFieldError 
    end 

    if params[:age] && !params[:age].blank? && params[:age].numeric? 
    @age = params[:age].to_i 
    else 
    raise MyApp::MissingFieldError 
    end 
rescue MyApp::MissingFieldError => err 
    flash[:error] = "Invalid form submission: #{err.clean_message}" 
    redirect_to :action => 'index' 
end 
+0

我想你不必使用params [:name]和!params [:name] .blank?在你的條件。 !PARAMS [:名字] .blank?足夠。 params [:name]返回false,如果它是零(沒有這樣的參數)和params [:name] .blank?如果爲零或爲空,則返回true。 – klew 2009-06-18 17:45:35

+0

你得到一個NoMethodError。我可以重寫NilClass來添加#blank?對,我想。 irb(main):002:0> params = {:a => 1,:b => 2,:c => 3} => {:c => 3,:a => 1,:b => 2} irb(main):003:0>!params [:name] .blank? NoMethodError:未定義的方法'空白?' for nil:NilClass from(irb):3 – 2009-06-19 14:13:04

+0

這裏沒有Ruby,只有Rails。 *已刪除的標籤* – Nakilon 2011-01-26 22:04:12

回答

25

你可以嘗試active_form(http://github.com/cs/active_form/tree/master/lib/active_form.rb) - 只是ActiveRecord減去數據庫的東西。這樣,您可以使用AR的所有驗證內容,並像對待其他任何模型一樣對待您的表單。

class MyForm < ActiveForm 
    validates_presence_of :name 
    validates_presence_of :graph_size, :if => # ...blah blah 
end 

form = MyForm.new(params[:form]) 
form.validate 
form.errors 
6

看起來你是在控制器做驗證,嘗試把它在模型中,它是更適合於那種事。

2

如果你今天再次來解決這個問題,你可以創建一個查詢參數集的模型,並使用Rails的內置的驗證,Rails 3中使這一切變得更加簡單::加載ActiveModel驗證看到this post