首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rails验证搜索参数

Rails验证搜索参数
EN

Stack Overflow用户
提问于 2012-05-25 05:51:08
回答 3查看 8.9K关注 0票数 4

我有一个相当restful的API,但我正在努力弄清楚如何实现干净的搜索。我希望能够搜索两个日期-时间之间的所有记录,日期-时间允许最多相隔6个小时。目前,在我的控制器方法中,我有以下内容:

代码语言:javascript
复制
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是一个应用程序方法,如下所示:

代码语言:javascript
复制
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非常类似。

我知道在控制器中进行验证是违反最佳实践的,但我不知道如何才能干净利落地将其添加到模型中。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-12-11 12:05:14

实际上,您正在做的是(几乎) best practice,并且将(几乎)与strong parametsers合并到Rails 4中。(我说几乎是因为您的check_max_time看起来应该是模型中的验证。)

你应该现在就把这个功能引入进来,让升级变得更容易。强参数https://github.com/rails/strong_parameters

文档在那里,但这里是如何合并它的。

代码语言:javascript
复制
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
票数 5
EN

Stack Overflow用户

发布于 2012-12-11 06:16:46

对于这个问题,从来没有找到一个干净的答案。但是,如果您正在编写一个应用程序接口,Grape具有内置的参数验证和强制机制来处理它。

票数 1
EN

Stack Overflow用户

发布于 2012-05-28 13:01:53

在这个场景中,我要做的是设置这两个日期时间之间的默认值,这样我就不必进行验证并引发异常。

代码语言:javascript
复制
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文档,说明这一事实。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10745814

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档