我有一个非常安静的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非常相似。
我知道在控制器中进行验证是违反最佳做法的,但我看不出如何干净地将它添加到模型中。
答案 0 :(得分:5)
实际上你正在做的事情(几乎)best practice
并且(几乎)将strong parametsers
合并到Rails 4中。 (我说几乎是因为你的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
答案 1 :(得分:1)
从未找到一个干净的答案。但是,如果您正在制作API Grape,则会使用内置的参数验证和强制来处理它。
答案 2 :(得分: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文档,说明这个事实。