Есть ли лучший подход для этого пользовательского Formtastic ввода в Rails?

Я использую Formtastic уже некоторое время, и это отлично подходит для ускорения реализации форм. Однако у меня есть особый случай, когда мне нужна дополнительная настройка в том, что отображается в моей форме. В частности, поле представляет собой форму загрузки файла для загрузки изображений, а в форме редактирования я хочу показать миниатюру текущей версии загруженного изображения.

Desired Form Output

у меня это работает, но для этого требуется, чтобы я использовал Пользовательский HTML разметка, что означает, что в любое время Formtastic изменяет формат вывода, мне нужно обновить соответствующий HTML. Вот что у меня есть сейчас:

<%= form.inputs do %>
    <% if form.object.new_record? -%>
        <%= form.input :image, :required => true, :hint => 'Maximum size of 3MB. JPG, GIF, PNG.' %>
    <% else -%>
        <li class="file input required" id="profile_image_input">
            <label class="label" for="profile_image">Image</label>
            <%= image_tag form.object.image.url(:thumb), :class => 'attachment' %>
            <%= form.file_field :image %>
            <p class="inline-hints">Maximum size of 3MB. JPG, GIF, PNG.</p>
        </li>
    <% end -%>
<% end %>

В идеале было бы неплохо сделать что-то вроде следующего, где input_html предполагается, что это сгенерированный HTML для ввода, подсказки и т. д.:

<%= form.inputs do %>
    <%= form.input :image, :required => true, :hint => 'Maximum size of 3MB. JPG, GIF, PNG.' do |input_html| %>
        <%= image_tag form.object.image.url(:thumb), :class => 'attachment' unless form.object.new_record? %>
        <%= input_html %>
    <% end %>
<% end %>

что-нибудь подобное уже есть? Или есть другой подобный вариант, который облегчит мою жизнь?

2 ответов


Ну, я решил это сам, конечно. Как всегда, когда я пишу здесь. : P

для тех, кто хочет сделать что-то подобное, я создал пользовательский тип ввода, полученный из ввода файла Formtastic.

class AttachmentInput < Formtastic::Inputs::FileInput
  def image_html_options
    {:class => 'attachment'}.merge(options[:image_html] || {})
  end

  def to_html
    input_wrapping do
      label_html <<
      image_html <<
      builder.file_field(method, input_html_options)
    end
  end

protected

  def image_html
    return "".html_safe if builder.object.new_record?

    url = case options[:image]
    when Symbol
      builder.object.send(options[:image])
    when Proc
      options[:image].call(builder.object)
    else
      options[:image].to_s
    end

    builder.template.image_tag(url, image_html_options).html_safe
  end
end

теперь я могу просто создать вход этого типа следующим образом:

<%= form.input :image, :as => :attachment,
                       :required => true,
                       :hint => 'Maximum size of 3MB. JPG, GIF, PNG.',
                       :image => proc { |o| o.image.url(:thumb) } %>

дополнительно :image тег может принять один из:

  • Proc, который передает объект формы param,
  • символ, который имя метода на объекте,
  • что-нибудь еще, которое преобразуется в строку и предполагается представлять URL.

кроме того, я могу использовать :image_html опция для указания классов HTML, идентификаторов и т. д.


в нижней части Formtastic docs в https://github.com/justinfrench/formtastic#modified--custom-inputs:

Create a file in app/inputs with a filename ending in _input.rb

недостаточно для полного решения, но после укоренения через formtastic источник для вдохновения смог придумать следующее, которое хорошо работает для меня.

в приложении / входы / label_input.rb:

class LabelInput
  include Formtastic::Inputs::Base

    def to_html
        input_wrapping do
            label_html <<
            "#{@object.send(method)}"
        end
    end
  end

случается использовать ActiveAdmin, в форме на странице:

form do |f|
  f.inputs do
    f.input :project
    f.input :date_consumed
    f.input :total_consumed
    f.input :computed_waste, :as => :label
    f.actions
  end
end