开发者

Trying to extend ActionView::Helpers::FormBuilder

I am trying to DRY up some code by moving some logic into the FormBuilder. After reading the documentation about how to select and alternative form builder the logical solution for me seemed t开发者_如何学Pythono be something like this.

In the view

<% form_for @event, :builder => TestFormBuilder do |f| %>
    <%= f.test  %>
    <%= f.submit 'Update' %>
<% end %>

and then in app/helpers/application_helper.rb

module ApplicationHelper
    class TestFormBuilder < ActionView::Helpers::FormBuilder
        def test
            puts 'apa'
        end
    end
end

This, however, gives me an error at the "form_for"

  uninitialized constant ActionView::Base::CompiledTemplates::TestFormBuilder

Where am I doing it wrong?


try with :

form_for @event, :builder => ApplicationHelper::TestFormBuilder do |f|


Builder class can be placed in module file, inside or/and outside module definition, like this:

    # app/helpers/events_helper.rb
    module EventsHelper
        ...
        class FormBuilderIn < ActionView::Helpers::FormBuilder
            ...
        end
    end
    class FormBuilderOut < ActionView::Helpers::FormBuilder
        ...
    end

Proper way to attach builder to form is:

    # app/views/events/_form_in.html.erb
    form_for @event, :builder => EventsHelper::FormBuilderIn do |f|

    # app/views/events/_form_out.html.erb
    form_for @event, :builder => FormBuilderOut do |f|

Here is helper method for setting builder option on form:

    # app/helpers/events_helper.rb
    module EventsHelper
      def form_in_for(data, *args, &proc)
          options = args.extract_options!
          form_for(data, *(args << options.merge(:builder => EventsHelper::FormBuilderIn)), &proc)
      end
      def form_out_for(data, *args, &proc)
          options = args.extract_options!
          form_for(data, *(args << options.merge(:builder => FormBuilderOut)), &proc)
      end
    end
    ...

Now, there is optional way to attach builder to form:

    # app/views/events/_form_in.html.erb
    form_in_for @event do |f|

    # app/views/events/_form_out.html.erb
    form_out_for @event do |f|

Finally, custom builders can be placed in separated folder, for example "app/builders", but this demands to manually add this path into application environment. For Rails 2.3.x, set:

    # config/environment.rb.
    config.load_paths += %W( #{RAILS_ROOT}/app/builders )


As you can see in http://guides.rubyonrails.org/configuring.html#configuring-action-view, you can set a default FormBuilder-class for your whole application. In your case:

config.action_view.default_form_builder = "ApplicationHelper::TestFormBuilder"
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜