我有一个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
方法继续,变量只是被分配为flat-out,不涉及检查:
@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文章,我现在使用特定于应用程序的异常.例如:
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
小智.. 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
Jamal Hansen.. 6
看起来你正在控制器中进行验证,尝试将其放入模型中,它更适合于那种事情.
你可以试试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
看起来你正在控制器中进行验证,尝试将其放入模型中,它更适合于那种事情.