2017-02-03 60 views
1

在我的Rails應用程序中,我想驗證filterpost_type參數。在Rails中驗證參數

兩者都是可選的,但如果它們存在,它們必須具有值並且必須具有與有效值數組中的值匹配的值。

在我的控制器我有檢查他們兩個方法:

def validate_filter 
    if params.has_key?(:filter) 
    if params[:filter].present? 
     if ['popular', 'following', 'picks', 'promoted', 'first-posts'].include?(params[:filter]) 
     return true 
     else 
     return false 
     end 
    else 
     return false 
    end 
    else 
    return true 
    end 
end 

def validate_post_type 
    if params.has_key?(:post_type) 
    if params[:post_type].present? 
     if ['discussions', 'snaps', 'code', 'links'].include?(params[:post_type]) 
     return true 
     else 
     return false 
     end 
    else 
     return false 
    end 
    else 
    return true 
    end 
end 

然後在我的主控制器的方法我做的:

def index 
    raise ActionController::RoutingError.new('Not Found') unless validate_filter && validate_post_type 
    ... 

因此,這意味着post_type=post_type=cam將返回404,但post_type=snaps將返回true。

有沒有更好的方法來驗證傳遞的params是否有效,但是這兩個參數都是空的,如果key本身存在。在這種情況下僅使用blank?present?是不夠的。

+0

如果應用程序使用RESTAPI然後嘗試使用[JSON-架構(https://github.com/ruby-json-schema/json-schema),而不是這樣的情況下,自定義的驗證。 –

回答

1

我可能會將這個邏輯轉移到模型上,但是如果你真的想在控制器中使用它,你可以簡化它。

def validate_filer 
    return true unless params.has_key?(:filter) 
    ['popular', 'following', 'picks', 'promoted', 'first-posts'].include?(params[:filter]) 
end 
+0

這很好,最小。我做得更苗條:'%w(流行的後續推介推廣的第一篇文章).include?(params [:filter])'就像@spickermann。 – Cameron

0

也許一個小的輔助方法:

def validate_filter 
    params_include?(:filter, %w(popular following picks promoted first-posts)) 
end 

def validate_filter 
    params_include?(:post_type, %w(discussions snaps code links)) 
end 

def params_include?(key, values) 
    !params.key?(key) || values.include?(params[key]) 
end 

它不是從你的問題是地方從PARAMS,如果他們是查詢參數或路徑的一部分來明確。如果它們是您可能考慮使用的路徑中的一部分routing constraints您的routes.rb

0

您可以在before_action中爲控制器操作執行此操作。

before_action: validate_params, only: [:index] 

def validate_params 
    return false unless params[:filter].present? && params[:post_type].present? 
    params_include?(:filter, %w(popular following picks promoted first-posts)) 
    params_include?(:post_type, %w(discussions snaps code links)) 
end