与动态加载(嵌套)表单字段中的模型无关的Rails 4文件上载

时间:2015-06-17 00:09:21

标签: ruby-on-rails file-upload nested-forms nested-attributes form-helpers

我正在寻找一种简单图像上传到文件系统的方法,这样图像就不会存储在数据库中。我理解这一步很简单,只需使用file_input标记,但由于我的表单是如何构建的,因此我遇到了问题。

我有一个项目,我通过让用户为页面指定页面布局或模板来创建静态活动页面。一旦用户选择了要为其页面加载的模板,就会加载一个表单,其中包含指定模板包含的每个窗口小部件的部分。用户输入他们的信息,按提交,然后创建静态页面。

其中一个小部件是一个图像小部件,用户应从系统中选择一个文件,并在提交表单时上传到服务器。问题在于,由于我使用表单助手的方式,我面临的问题是文件上传将文件名作为字符串而不是IO对象(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#uploading-files)和其他问题报告后,我的理解是问题是“multipart => true”,如果您希望文件字段标记起作用,则必须指定该问题。这应该不是问题,因为我使用的是form_for @campaign_page而不是form_tag。但是,窗口小部件及其内容不属于广告系列页面表格,因此未在广告系列页面的模型中指定。因此,我不能简单地使用f.file_field作为文件输入。

我正在寻找解决方案。是使用嵌套属性然后使用field_for进行图像上传工作吗?

另一个问题是小部件的规范和内容存储在Postgres JSONB字段中,我不确定嵌套属性如何适用于那些。

1 个答案:

答案 0 :(得分:0)

我假设表单有多部分集,因为指定multipart =>根据Rails文档,没有必要使用form_for帮助程序。然而,修复结果非常简单 - 在表单标记的html选项哈希中设置multipart:true后,它可以正常工作:

= form_for(@campaign_page, class: 'form-horizontal', html: {multipart: true}) do |f|
...