Независимая от модели загрузка файла Rails 4 в динамически загружаемом (вложенном) поле формы

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

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

Одним из виджетов является виджет изображения, где пользователь должен выбрать файл из своей системы, и он должен быть загружен на сервер при отправке формы. Проблема в том, что из-за того, как я использую помощники форм, я сталкиваюсь с проблемой, когда загрузка файла дает имя файла в виде строки вместо объекта ввода-вывода ( https://www.ruby-forum.com/topic/125637). Мне нужна помощь, чтобы попытаться обойти это.

Форма для ввода данных на страницу (которая хранится в таблице campaign_pages) выглядит следующим образом:

= form_for(@campaign_page, class: 'form-horizontal') do |f|
  fieldset
    legend Basic page information
    .form-group
      = f.label :featured, class: 'control-label col-lg-2'
      .col-lg-10
        = f.check_box :featured, class: 'form-control'

      = f.label :title, class: 'control-label col-lg-2'
      .col-lg-10
        = f.text_field :title, placeholder: 'Unique and really catchy page title!', class: 'form-control'

      = f.label :campaign_id, 'Campaign: ', class: 'control-label col-lg-2'
      .col-lg-10
        = f.select :campaign_id, options_from_collection_for_select(@campaigns, 'id', 'campaign_name', @campaign), {}, html_options= {:class => 'form-control'}

      = f.label :language_id, 'Language: ', class: 'control-label col-lg-2'
  .col-lg-10
        = f.select :language_id, options_from_collection_for_select(Language.all,'id', 'language_name'), {}, html_options= {:class => 'form-control'}

      label for='template_id' class='control-label col-lg-2' Template: 
  .col-lg-10
        = select_tag 'template_id', options_from_collection_for_select(@templates, 'id', 'template_name', @template), class: 'form-control'
      | data-no-turbolink="true"

Вот где формы для контента для каждого виджета на странице загружаются после выбора шаблона:

    #widget_location
      = render :file => 'templates/show_form', layout: false

    .form-group
      = f.submit 'Save Page', class: 'btn btn-sm btn-primary'

Форма для виджета изображения (который создает проблему) выглядит так:

#image_widget_form.form-group
  = label_tag 'widgets[image][image_url]', 'Image URL:', class: 'control-label col-lg-2'
  .col-lg-10
    = text_field_tag 'widgets[image][image_url]', options['image_url'], class: 'form-control'
    = hidden_field_tag 'widgets[image][widget_type]', WidgetType.find_by(:widget_name => 'image').id
    = file_field_tag 'widgets[image][image_upload]'

После прочтения документации ( http://guides.rubyonrails.org/form_helpers.html) и других отчетов о проблемах я понимаю, что проблема заключается в "multipart => true", которую вы должны указать, если хотите тег вашего поля файла для работы. Это не должно быть проблемой, потому что я использую form_for @campaign_page вместо form_tag. Однако виджеты и их содержимое не принадлежат таблице страниц кампании, поэтому они не указаны в модели для страницы кампании. Таким образом, я не могу просто использовать f.file_field для ввода файла.

Я ищу решение для этого. Будет ли работать вложенные атрибуты, а затем использовать field_for для загрузки изображений?

Другая проблема заключается в том, что спецификации и контент для виджетов хранятся в поле Postgres JSONB, и я не уверен, как для них будут работать вложенные атрибуты.

1 ответ

Решение

Я предполагал, что форма имеет множественный набор, потому что указание multipart => true для помощника form_for не является обязательным в соответствии с документацией Rails. Исправление оказалось довольно простым, однако - оно работает после установки multipart: true в хэш html-параметров для тега формы:

= form_for(@campaign_page, class: 'form-horizontal', html: {multipart: true}) do |f|
...
Другие вопросы по тегам