2013-07-27 33 views
2

是否有一种方法可以将隐藏的输入字段添加到在轨道中在视图中声明的所有窗体。隐藏字段需要具有由控制器中的公共属性传递的值。基本上我想要任何由Web服务器作为响应给出的表单,以具有额外的隐藏输入元素。向轨道中的所有窗体添加隐藏的输入字段

我该怎么做?我可以用某种方式覆盖form_for吗?或者我可以用部分中的表单包装来强制每个人使用部分?

回答

4

编辑:好的,我的第一次传递不起作用,因为你不能在初始化器中定义一个值,你稍后要从控制器传入。所以你可以通过两种方式来解决这个问题。 您可以定义CustomFormBuilder类 - 把它放在一个初始化 -

class CustomFormBuilder < ActionView::Helpers::FormBuilder 
    def submit(value, options = {}) 
    @template.hidden_field_tag(options.delete(:custom_param)) + super 
    end 
end 

然后通过:builder选项form_for

form_for @whatever, builder: CustomFormBuilder 

,并假设你的形式,其中的选项包括您CUSTOM_PARAM打电话submit(value, options),它将被自定义方法覆盖,该方法将隐藏字段插入到所需的值中。

另一种方法是猴补丁猴补丁FormTagHelper代替:

module ActionView::Helpers::FormTagHelper 

    def extra_tags_for_form_with_custom_param(html_options) 
    hidden_field_tag(html_options.delete('custom_param') + 
    extra_tags_for_form_without_custom_param(html_options) 
    end 
    alias_method_chain :extra_tags_for_form, :custom_param 
end 

这就是调整的代码form_for使用在每一个表格的顶部插入真实性令牌。现在你可以在控制器中设置它作为一个实例变量之后传递的自定义参数去form_for

form_for @object, custom_param: @custom_param do |f| 

如果您在使用Ruby 2.0+那么你可以使用模块前插,而不是过时的alias_method_chain例如

module CustomParamFormPatch 
    private 
    def extra_tags_for_form(html_options) 
    hidden_field_tag(html_options.delete('custom_param')) + 
    super 
    end 
end 

ActionView::Base.prepend(CustomParamFormPatch) 
+0

我试着指定submit_Tag(value,options = {})。它似乎不呈现隐藏的输入元素。我还添加了一条似乎不起作用的日志声明。我正确地附加了建造者。我的表单全部使用submit_tag。我错过了什么? – gnarsi

+0

'submit_tag'没有在FormBuilder类中定义,'submit'是。由于'submit_tag'被调用...实际上我不确定哪些对象调用了这些* _tag方法,@template也许 - 我不认为你可以继承它。你必须在FormTagHelper类中修饰'submit_tag',这对我来说更加脆弱。任何你不仅仅使用'submit'的理由? – bgates

+0

我不确定为什么它不是首先提交。我现在将其转换为提交。但是有没有一种方法可以访问当前的控制器实例并得到像我这样的属性?我没有找到办法做到这一点。 – gnarsi