我有一个Rails应用程序,允许用户通过填写一个扩展的表单来构建数据库查询。我想知道在Rails中检查表单参数的最佳实践。以前,我使用results
方法(表单提交的方法)执行以下操作:
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 Buck的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 :(得分: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
答案 1 :(得分:6)
看起来你正在控制器中进行验证,试着把它放在模型中,它更适合那种东西。
答案 2 :(得分:2)
如果你今天要再次解决这个问题,你可以为查询参数集创建一个模型并使用Rails内置的验证,Rails 3使用ActiveModel :: Validations更容易看到this post。
答案 3 :(得分:0)
class Person
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :name
attr_accessor :email
validates_presence_of :name,:message => "Please Provide User Name"
validates_presence_of :email,:message => "Please Provide Email"
end
请注意,您不一定需要保存/保留模型以进行验证。
@person.name= params["name"]
@person.email= params["email"]
@person.valid?
您叫一个有效的吗?方法上的错误,错误将填充在@person对象内。因此,
<%if @person.errors.any? %>
<%@person.errors.messages.each do|msg| %>
<div class="alert alert-danger">
<%=msg[0][1]%>
</div>
<%end%>
<%end%>