2008-12-11 90 views
20

我有一个Rails应用程序,可以让用户通过填写​​一个广泛的窗体来构建数据库查询。我想知道在Rails中检查表单参数的最佳做法。以前,我有我的results方法(一个表单提交)执行以下操作:Rails窗体验证

if params[:name] && !params[:name].blank? 
    @name = params[:name] 
else 
    flash[:error] = 'You must give a name' 
    redirect_to :action => 'index' 
    return 
end 

但对于一些表单字段,看到这个重复每一个有烦人。我不能只是坚持他们都在一些循环来检查每个字段,因为字段的设置有所不同:

  • 一个键:params[:name]
  • 键和子键:params[:image][:font_size]
  • 只希望如果其他字段设置

等,这也是重复的,因为我是为每个缺少/无效参数设置flash[:error],并重定向到为每一个相同的URL某种形式的字段填写。我切换到使用before_filter,检查所有必要的表单参数,只有在一切正常时才返回true。然后我results方法继续和变量只是分配平展,没有检查涉及:

@name = params[:name] 

在我validate_form的方法,我有如下所示的代码段:

if (
    params[:analysis_type][:to_s] == 'development' || 
    params[:results_to_generate].include?('graph') 
) 
    {:graph_type => :to_s, :graph_width => :to_s, 
    :theme => :to_s}.each do |key, sub_key| 
    unless params[key] && params[key][sub_key] 
     flash[:error] = "Cannot leave '#{Inflector.humanize(key)}' blank" 
     redirect_to(url) 
     return false 
    end 
    end 
end 

我只是想知道我是否以最好的方式解决这个问题,或者如果我在参数验证方面失去了一些显而易见的东西。我担心这仍然不是最有效的技术,因为我有几个块,我将值赋给flash[:error],然后重定向到相同的URL,然后返回false。

编辑澄清:我之所以没有在模型(一个或多个)这个验证目前有两个原因:

  • 我并不想从用户那里收集数据,以便创建或更新数据库中的一行。用户提交的数据在注销后都不会保存。当它们提交它来搜索数据库并生成一些东西时,它们都是正确的。
  • 查询表单接收与几个模型有关的数据,并且它接收其他与模型无关的数据。例如。上面显示的图形类型和主题不连接到任何模型,它们只是传达有关用户如何显示其结果的信息。

编辑显示改进的技术:我使用的应用程序特定的例外,现在,多亏了Jamis巴克的Raising the Right Exception article。例如:

def results 
    if params[:name] && !params[:name].blank? 
    @name = params[:name] 
    else 
    raise MyApp::MissingFieldError 
    end 

    if params[:age] && !params[:age].blank? && params[:age].numeric? 
    @age = params[:age].to_i 
    else 
    raise MyApp::MissingFieldError 
    end 
rescue MyApp::MissingFieldError => err 
    flash[:error] = "Invalid form submission: #{err.clean_message}" 
    redirect_to :action => 'index' 
end 
+0

我想你不必使用params [:name]和!params [:name] .blank?在你的条件。 !PARAMS [:名字] .blank?足够。 params [:name]返回false,如果它是零(没有这样的参数)和params [:name] .blank?如果为零或为空,则返回true。 – klew 2009-06-18 17:45:35

+0

你得到一个NoMethodError。我可以重写NilClass来添加#blank?对,我想。 irb(main):002:0> params = {:a => 1,:b => 2,:c => 3} => {:c => 3,:a => 1,:b => 2} irb(main):003:0>!params [:name] .blank? NoMethodError:未定义的方法'空白?' for nil:NilClass from(irb):3 – 2009-06-19 14:13:04

+0

这里没有Ruby,只有Rails。 *已删除的标签* – Nakilon 2011-01-26 22:04:12

回答

25

你可以尝试active_form(http://github.com/cs/active_form/tree/master/lib/active_form.rb) - 只是ActiveRecord减去数据库的东西。这样,您可以使用AR的所有验证内容,并像对待其他任何模型一样对待您的表单。

class MyForm < ActiveForm 
    validates_presence_of :name 
    validates_presence_of :graph_size, :if => # ...blah blah 
end 

form = MyForm.new(params[:form]) 
form.validate 
form.errors 
6

看起来你是在控制器做验证,尝试把它在模型中,它是更适合于那种事。

2

如果你今天再次来解决这个问题,你可以创建一个查询参数集的模型,并使用Rails的内置的验证,Rails 3中使这一切变得更加简单::加载ActiveModel验证看到this post