Вопрос по ruby, ruby-on-rails, ruby-on-rails-3, validation – Rails проверяет параметры поиска

3

У меня есть API, который довольно спокойный, но я пытаюсь понять, как правильно реализовать поиск. Я хочу иметь возможность искать все записи между двумя датами, время и дата могут быть максимально с интервалом 6 часов. На данный момент в моем методе контроллера у меня есть следующее:

required_params = [:start_time, :end_time]
if check_required_params(required_params, params) and check_max_time_bound(params, 6.hours)
   ... rest of controller code here ...
end

check_required_params - это метод приложения, который выглядит следующим образом:

def check_required_params(required_params, params_sent)
required_params.each do |param|
  unless has_param(param, params_sent)
    unprocessable_entity
    return false
  end
end
  true
end

check_max_time довольно похож.

Я знаю, что это противоречит передовым методам проверки в контроллере, но я не вижу, как правильно добавить его в модель.

@tokland Хорошо, я могу это сделать. Думаю, я надеялся, что смогу использовать встроенные проверки Active :: Model. Mike
Мне нравится вопрос, но я не понимаю, что мешает вам переместить весь этот код (кромеunprocessable_entity) к модели. Обратите внимание, чтоcheck_required_params можно много упростить, используя пересечения массивов, не нужно зацикливаться. tokland

Ваш Ответ

3   ответа
1

Никогда не нашел четкого ответа на это. Однако, если вы создаете APIвиноград имеет встроенную проверку параметров и принуждение, чтобы позаботиться об этом.

0

Хорошо, что я хотел бы сделать в этом сценарии, так это установить значение по умолчанию между этими двумя датами, чтобы мне не пришлось проверять и выдавать исключение.

class SearchController < ApplicationController
  before_filter :assign_default_params

  def index
  end

  private
  def assign_default_params
    params[:start_time] ||= Time.now
    params[:end_time]   ||= params[:start_time] + 6.hours
    params[:end_time]     = params[:start_time] + 6.hours if ((params[:end_time] - params[:start_time]) / 3600).round) > 6
  end
end

С этим кодом выше у него всегда есть параметры, необходимые для поиска. Методassign_default_params попробуйте назначить значения по умолчанию, если они не отправлены с клиентов. Последнее, что он делает, - это назначаетparams[:end_time] до максимального значения.

Это намного лучше, потому что нам не нужно выполнять проверку, а клиенту не нужно обрабатывать другой код ответа, такой как422, И у вас должна быть документация по API, в которой также указывается этот факт.

Да, я согласен. Но я бы предпочел ошибку, если потребитель API попытается сделать что-то глупое, а не молча изменить свое мнение. Mike
А как насчет проверки дат с интервалом не более 6 часов? Mike
API должен иметь документацию, поэтому люди, потребляющие API, должны знать, и как он ведет себя как API Twitter и API API Graph Graph.
Спасибо за Ваш ответ. Я думаю, что я бы вернул 422 ... в противном случае он мог бы дать неожиданные результаты для людей, использующих API. Mike
я только что обновил свой ответ.
5

На самом деле то, что вы делаете, это (почти)best practice и (почти) будет включен в Rails 4 сstrong parametsers, (Я говорю почти потому, что вашcheck_max_time похоже, это должна быть проверка в вашей модели.)

Вы должны пойти дальше и использовать эту функцию сегодня и упростить обновление для себя. Сильные Параметрыhttps://github.com/rails/strong_parameters

Документация есть, но вот как вы ее включили.

class SearchController < ApplicationController
  include ActiveModel::ForbiddenAttributesProtection

  def create
    # Doesn't have to be an ActiveRecord model
    @results = Search.create(search_params)
    respond_with @results
  end

  private

  def search_params
    # This will ensure that you have :start_time and :end_time, but will allow :foo and :bar
    params.require(:start_time, :end_time).permit(:foo, :bar #, whatever else)
  end
end

class Search < ActiveRecord::Base
  validates :time_less_than_six_hours

  private

  def time_less_than_six_hours
    errors.add(:end_time, "should be less than 6 hours from start") if (end_time - start_time) > 6.hours
  end
end
Похоже на вашregistration_id это строка, а не хэш. Перепишите это так:params[:user].require(:registration_id); params[:user].permit(:device_name, :os_type), Способ работы Сильных Параметров изменился.

Похожие вопросы