Есть ли способ создать пользовательский помощник формы, чтобы вместо:
special_field_tag :object, :method
Я могу добиться чего-то вроде:
form.special_field :method
Есть ли способ создать пользовательский помощник формы, чтобы вместо:
special_field_tag :object, :method
Я могу добиться чего-то вроде:
form.special_field :method
Да, вы можете добавить к классу FormBuilder и получить доступ к объекту, переданному в form_for. Я сделал это для многих вещей: даты, время, измерения и т.д. Вот пример:
class ActionView::Helpers::FormBuilder
include ActionView::Helpers::TagHelper
include ActionView::Helpers::FormTagHelper
include ActionView::Helpers::FormOptionsHelper
include ActionView::Helpers::CaptureHelper
include ActionView::Helpers::AssetTagHelper
# Accepts an int and displays a smiley based on >, <, or = 0
def smile_tag(method, options = {})
value = @object.nil? ? 0 : @object.send(method).to_i
options[:id] = field_id(method,options[:index])
smiley = ":-|"
if value > 0
smiley = ":-)"
elsif smiley < 0
smiley = ":-("
end
return text_field_tag(field_name(method,options[:index]),options) + smiley
end
def field_name(label,index=nil)
output = index ? "[#{index}]" : ''
return @object_name + output + "[#{label}]"
end
def field_id(label,index=nil)
output = index ? "_#{index}" : ''
return @object_name + output + "_#{label}"
end
end
Что вы можете использовать следующим образом:
<% form_for @quiz do |f| %>
<%= f.smile_tag(:score) %>
<% end %>
Есть несколько переменных экземпляра, созданных Rails, которые вы можете получить в этих вспомогательных методах:
Я написал методы field_id и field_name для создания этих атрибутов на элементах ввода HTML так же, как обычные помощники, я уверен, что есть способ связать те же методы, что и Rails, но у меня нет нашел его еще.
Небо - это предел того, что вы можете сделать с помощью этих вспомогательных методов, они просто возвращают строки. Вы можете создавать целые HTML-таблицы или страницы в одном, но у вас есть все основания.
Этот файл должен быть добавлен в папку приложения/помощников
@Tilendor, большое спасибо за указатели. Ниже приведен пример помощника тега enum_select
, который использует списки Rails 4.1 для автоматического заполнения опций тега select:
# helpers/application_helper.rb
module ApplicationHelper
class ActionView::Helpers::FormBuilder
# http://stackoverflow.com/a/2625727/1935918
include ActionView::Helpers::FormTagHelper
include ActionView::Helpers::FormOptionsHelper
def enum_select(name, options = {})
# select_tag "company[time_zone]", options_for_select(Company.time_zones
# .map { |value| [value[0].titleize, value[0]] }, selected: company.time_zone)
select_tag @object_name + "[#{name}]", options_for_select(@object.class.send(name.to_s.pluralize)
.map { |value| [value[0].titleize, value[0]] }, selected: @object.send(name))
end
end
end
Самая сложная конструкция - @object.class.send(name.to_s.pluralize)
, которая создает хэш доступных значений (например, Company.time_zones
). Ввод его в helpers/application_helper.rb
делает его автоматически доступным. Он используется как:
<%= f.label :billing_status %>:
<%= f.enum_select :billing_status %><br />
В нашем приложении отображались номера телефонов в текстовых полях, и мы хотели опустить код страны для внутренних номеров. Я использовал помощников формы. После прочтения этого и рельсов источник немного, я пришел к этому решению:
class ActionView::Helpers::FormBuilder
def phone_text_field name, options = {}
value = object.public_send(name).to_s
if value.start_with? "9" # national number
value = value[1..-1]
options["value"] = value
end
text_field name, options
end
end
Я помещаю это в app/helpers/application_helper.rb и использую его, как я использую text_field()
помощник. Надеюсь, это поможет кому-то.