Rails构成验证 [英] Rails form validation
问题描述
我有一个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的所有验证内容,并像对待其他任何模型一样对待您的表单。
ActiveFormvalidates_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屋!