在我的Rails应用中,我想验证filter
和post_type
参数。
两者都是可选的,但如果它们存在,则它们必须具有值,并且必须具有与有效值数组中的值匹配的值。
在我的控制器中,我有两种方法可以检查它们:
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。
是否有更好的方法来验证传递的参数是否有效,但是如果密钥本身存在则为空。在这种情况下,仅使用blank?
和present?
是不够的。
答案 0 :(得分:1)
我可能会将此逻辑移至模型中,但如果您真的想在控制器中使用它,则可以简化它。
def validate_filer
return true unless params.has_key?(:filter)
['popular', 'following', 'picks', 'promoted', 'first-posts'].include?(params[:filter])
end
答案 1 :(得分: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
如果它们是查询参数或路径的一部分,则从您的问题中不清楚这些参数的来源。如果他们是路径的一部分,您可以考虑在routes.rb
答案 2 :(得分:0)
您可以在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
中执行此操作以执行控制器操作。
Der
答案 3 :(得分:0)
在使用API的情况下,我会考虑让客户端知道存在验证错误,而不仅仅是说404。
如何使用ActiveModel::Validations
?
class MyParamsValidator
include ActiveModel::Validations
AVAILABLE_FILTERS = %w(popular following picks promoted first-posts)
# this might come from an enum like MyModel.post_types
AVAILABLE_POST_TYPES = %w(discussions snaps code links)
attr_reader :data
validates :filter, inclusion: { in: AVAILABLE_FILTERS }, allow_blank: true
validates :post_type, inclusion: { in: AVAILABLE_POST_TYPES }, allow_blank: true
def initialize(data)
@data = data
end
def read_attribute_for_validation(key)
data[key]
end
end
class MyController < ApplicationController
before_action :validate_params, only: :index
def validate_params
validator = MyParamsValidator.new(params)
return if validator.valid?
render json: { errors: validator.errors }, status: 422
end
end
您可以通过一些测试here找到有关嵌套案例的更多信息。