Попытка расширить ActionView::Helpers::FormBuilder

Я пытаюсь высушить некоторый код, переместив некоторую логику в FormBuilder. После прочтения документации о том, как выбрать и альтернативный конструктор форм, логичным решением для меня стало что-то вроде этого.

В представлении

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

а затем в app/helpers/application_helper.rb

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

Это, однако, дает мне ошибку в "form_for"

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

Где я делаю это неправильно?


person Felix Andersen    schedule 19.03.2010    source источник


Ответы (3)


попробуйте с:

form_for @event, :builder => ApplicationHelper::TestFormBuilder do |f|
person shingara    schedule 19.03.2010
comment
Спасибо. Это сработало. Это где-то задокументировано или я что-то пропустил в структуре рельсов? - person Felix Andersen; 19.03.2010
comment
Вам нужно определить класс. Так что вам не нужно помещать его в свой ApplicationHelper. Таким образом, вы можете поместить свой класс в свою библиотеку и использовать без пространства имен. - person shingara; 19.03.2010
comment
Есть ли более элегантный способ, чем этот? - person JohnMerlino; 18.04.2014

Класс Builder может быть помещен в файл модуля, внутри и/или вне определения модуля, например:

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

Правильный способ присоединения построителя к форме:

    # 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|

Вот вспомогательный метод для установки опции построителя в форме:

    # 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
    ...

Теперь есть дополнительный способ прикрепить билдер к форме:

    # 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|

Наконец, пользовательские сборщики можно поместить в отдельную папку, например, «app/builders», но для этого необходимо вручную добавить этот путь в среду приложения. Для Rails 2.3.x установите:

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

Как видно из http://guides.rubyonrails.org/configuring.html#configuring-action-view, вы можете установить класс FormBuilder по умолчанию для всего вашего приложения. В твоем случае:

config.action_view.default_form_builder = "ApplicationHelper::TestFormBuilder"
person mmichaa    schedule 02.03.2012