Rails构成验证 [英] Rails form validation

查看:109
本文介绍了Rails构成验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  if params [:name]&& !PARAMS [:名字] .blank? 
@name = params [:name]
else
flash [:error] ='您必须提供一个名称'
redirect_to:action => 'index'
return
end

但是对于多个表单字段,每个人重复都会让人厌烦。我不能将它们全部粘在一些循环中来检查每个字段,因为这些字段的设置不同:




  • 单个键: params [:name]

  • 一个键和一个子键: params [:image] [ :font_size]

  • 只有在设置了另一个字段时才需要填写某些表单域


等等。这也是重复性的,因为我为每个丢失/无效的参数设置了 flash [:error] ,并重定向到每个URL的相同URL。我切换到使用 before_filter 来检查所有必要的表单参数,只有在一切正常时才返回true。然后继续执行我的结果方法,并将变量分配为扁平状态,而不涉及任何检查:

<$ p $ @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 |
除非params [key]&& params [key] [sub_key]
flash [:error] =不能离开'#{Inflector.humanize(key)}''空白'
redirect_to(url)
返回false
结束
结束
结束

我只是想知道我是否要去关于这个最好的方法,或者如果我在参数验证时错过了一些明显的东西。我担心这仍然不是最有效的技术,因为我有几个块为 flash [:error] 赋值,然后重定向到相同的URL,然后返回false。



编辑澄清:目前,我在模型中没有此验证的原因有两个原因: p>


  • 我不想从用户那里收集数据来创建或更新数据库中的一行。用户提交的数据在注销后都不会保存。当它们提交它来搜索数据库并生成一些内容时,它们都是正确的。

  • 查询表单接收与多个模型有关的数据,并且其他数据不涉及到一个模型。例如。图表类型和主题没有连接到任何模型,他们只是传达有关用户如何显示他的结果的信息。


编辑以显示改进的技术:现在我利用特定于应用程序的异常,这要归功于Jamis Buck的提出正确的例外条款。例如:

  def结果
if params [:name]&& !PARAMS [:名字] .blank?
@name = params [:name]
else
提升MyApp :: MissingFieldError
结束

if params [:age]&& !PARAMS [:年龄] .blank? &安培;&安培; PARAMS [:年龄] .numeric?
@age = params [:age] .to_i
else
提高MyApp :: MissingFieldError
结束
rescue MyApp :: MissingFieldError => err
flash [:error] =表单提交无效:#{err.clean_message}
redirect_to:action => 'index'
end


解决方案

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

ActiveForm
validates_presence_of:name
validates_presence_of:graph_size,:if => #... blah blah
end
$ b form = MyForm.new(params [:form])
form.validate
form.errors


I have a Rails app that lets a user construct a database query by filling out an extensive form. I wondered the best practice for checking form parameters in Rails. Previously, I have had my results method (the one to which the form submits) do the following:

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

But for several form fields, seeing this repeated for each one got tiresome. I couldn't just stick them all in some loop to check for each field, because the fields are set up differently:

  • a single key: params[:name]
  • a key and a sub-key: params[:image][:font_size]
  • only expect some form fields to be filled out if another field was set

Etc. This was also repetitive, because I was setting flash[:error] for each missing/invalid parameter, and redirecting to the same URL for each one. I switched to using a before_filter that checks for all necessary form parameters and only returns true if everything's okay. Then the my results method continues, and variables are just assigned flat-out, with no checking involved:

@name = params[:name]

In my validate_form method, I have sections of code like the following:

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

I was just wondering if I'm going about this in the best way, or if I'm missing something obvious when it comes to parameter validation. I worry this is still not the most efficient technique, because I have several blocks where I assign a value to flash[:error], then redirect to the same URL, then return false.

Edit to clarify: The reason I don't have this validation in model(s) currently is for two reasons:

  • I'm not trying to gather data from the user in order to create or update a row in the database. None of the data the user submits is saved after they log out. It's all used right when they submit it to search the database and generate some stuff.
  • The query form takes in data pertaining to several models, and it takes in other data that doesn't pertain to a model at all. E.g. graph type and theme as shown above do not connect to any model, they just convey information about how the user wants to display his results.

Edit to show improved technique: I make use of application-specific exceptions now, thanks to Jamis Buck's Raising the Right Exception article. For example:

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

解决方案

You could try active_form (http://github.com/cs/active_form/tree/master/lib/active_form.rb) - just ActiveRecord minus the database stuff. This way you can use all of AR's validation stuff and treat your form like you would any other model.

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

这篇关于Rails构成验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆