как правильно расширить form_for / ActionView :: Helpers :: FormBuilder? - PullRequest
3 голосов
/ 08 июня 2011

Это похоже на Попытка расширить ActionView :: Helpers :: FormBuilder , но я не хочу использовать: builder => MyThing.

Я хочу расширить конструктор форм для добавления пользовательских методов. Это текущая ситуация:

module ActsAsTreeHelpers
  def acts_as_tree_block(method, &block)
    yield if block_given?
  end

end


ActionView::Helpers::FormBuilder.send :include, ::ActsAsTreeHelpers

Консоль

ruby-1.9.2-p180 :004 > ActionView::Helpers::FormBuilder.included_modules
=> [ActsAsTreeHelpers, ...]

Но мне дает следующее: undefined method acts_as_tree_block for #<ActionView::Helpers::FormBuilder:0xae114dc>

<%= form_for thing do |form| %>
  <%= form.acts_as_tree_block :parent_id, {"test"} %>
<% end %>

Что мне здесь не хватает?

Ответы [ 2 ]

5 голосов
/ 30 августа 2011

У меня тоже была такая же проблема.Я попытался добавить новый файл с именем form_builder.rb в папку config / initializers моего проекта, и теперь он работает хорошо.

Ниже приведено некоторое содержание моего решения.base_helper.rb

def field_container(model, method, options = {}, &block)
  css_classes = options[:class].to_a
  if error_message_on(model, method).present?
    css_classes << 'withError'
  end
  content_tag('p', capture(&block), :class => css_classes.join(' '), :id => "#{model}_#{method}_field")
end

form_builder.rb

class ActionView::Helpers::FormBuilder
  def field_container(method, options = {}, &block)
    @template.field_container(@object_name,method,options,&block)
  end

  def error_message_on(method, options = {})
    @template.error_message_on(@object_name, method, objectify_options(options))
  end
end
ActionView::Base.field_error_proc = Proc.new{ |html_tag, instance| "<span class=\"field_with_errors\">#{html_tag}</span>".html_safe }

_form.html.erb

<%= f.field_container :name do %>
  <%= f.label :name, t("name") %> <span class="required">*</span><br />
  <%= f.text_field :name %>
  <%= f.error_message_on :name %>
<% end %>
0 голосов
/ 27 мая 2019

Принятый ответ больше не работал для меня (Rails 5 +)

Вот изменения, которые я сделал, чтобы заставить его работать (Rails 5.2.3):

# config/initializers/custom_form_builder.rb
class ActionView::Helpers::FormBuilder
  def my_custom_text_field_with_only_letters(method, options = {})
    options[:pattern] = "^[A-Za-z]+$"
    options[:title] = "Only letters please"
    text_field(method, options)
  end

  field_helpers << :my_custom_text_field_with_only_letters
end

field_helpers << :my_custom_text_field_with_only_letters гарантирует, что ваш новый метод доступен изначально во всех ваших формах приложения.

Согласно doc , другой возможностью является расширение FormBuilder, добавление вашего пользовательского метода, а затем указание в каждом из них.из ваших требуемых форм, которые FormBuilder использовать:

class MyFormBuilder < ActionView::Helpers::FormBuilder
 def div_radio_button(method, tag_value, options = {})
...

<%= form_for @person, :builder => MyFormBuilder do |f| %>
<%= f.div_radio_button(:admin, "child") %>
...