2017-02-03 3 views
1

В моем приложении Rails я хочу проверить параметры filter и post_type.Validate params in 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.

Есть ли лучший способ проверить, что переданные параметры действительны, но для обоих пустых и если сам ключ существует. В этом сценарии недостаточно всего 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])' like @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