Rails:多文件上传生成一个空条目

SEJ*_*EJU 3 ruby-on-rails carrierwave

我正在尝试创建某种嵌套文件上传。我有图像和相册,它们通过模型 AlbumImages 相关。图像可以是相册的一部分。上传是通过Carrierwave进行的。

\n

我希望能够通过两种方式上传图像:

\n
    \n
  1. 直接通过图像
  2. \n
  3. 通过相册
  4. \n
\n

通过相册上传图像时,应将它们上传并插入到 Images 和 AlbumImages 表中。

\n

我可以通过图像上传单个图像,但令我惊讶的是,我当前通过相册上传多个图像的实现会产生 2 个单独的数据条目。(这曾经在 Rails 3 下工作)第一个条目是空的,第二个条目是我的目标。

\n
Started PATCH "/admin/albums/38" for ::1 at 2022-05-20 11:18:44 +0200\nProcessing by Admin::AlbumsController#update as HTML\n  Parameters: {"authenticity_token"=>"[FILTERED]", "album"=>{"images_attributes"=>[{"file_name"=>""}, {"file_name"=>#<ActionDispatch::Http::UploadedFile:0x00007f8f75185c70 @tempfile=#<Tempfile:/var/folders/yg/pfjwzpkx5wq9d27svk760h0h0000gn/T/RackMultipart20220520-19476-kto7za.jpg>, @original_filename="some-image.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\\"album[images_attributes][][file_name]\\"; filename=\\"some-image.jpg\\"\\r\\nContent-Type: image/jpeg\\r\\n">, "author"=>"Some Author", "copyright"=>"Someone", "funds_ids"=>["1", "6"]}]}, "commit"=>"Save", "id"=>"38"}\n  Admin Load (0.3ms)  SELECT `admins`.* FROM `admins` WHERE `admins`.`id` = 1 ORDER BY `admins`.`id` ASC LIMIT 1\n  Album Load (0.2ms)  SELECT `albums`.* FROM `albums` WHERE `albums`.`id` = 38 LIMIT 1\n  \xe2\x86\xb3 app/controllers/admin/albums_controller.rb:39:in `update'\n  TRANSACTION (0.2ms)  BEGIN\n  \xe2\x86\xb3 app/controllers/admin/albums_controller.rb:40:in `update'\n  Fund Load (0.5ms)  SELECT `funds`.* FROM `funds` WHERE `funds`.`id` IN (1, 6)\n  \xe2\x86\xb3 app/controllers/admin/albums_controller.rb:40:in `update'\n  Section Load (0.3ms)  SELECT `sections`.* FROM `sections` WHERE `sections`.`id` = 5 LIMIT 1\n  \xe2\x86\xb3 app/controllers/admin/albums_controller.rb:40:in `update'\n  Fund Exists? (0.3ms)  SELECT 1 AS one FROM `funds` WHERE `funds`.`name` = 'SomeFundA' AND `funds`.`id` != 1 LIMIT 1\n  \xe2\x86\xb3 app/controllers/admin/albums_controller.rb:40:in `update'\n  Fund Exists? (0.2ms)  SELECT 1 AS one FROM `funds` WHERE `funds`.`name` = 'SomeFundB' AND `funds`.`id` != 6 LIMIT 1\n  \xe2\x86\xb3 app/controllers/admin/albums_controller.rb:40:in `update'\n  Album Exists? (0.2ms)  SELECT 1 AS one FROM `albums` WHERE `albums`.`title` = 'SomeAlbum' AND `albums`.`id` != 38 LIMIT 1\n  \xe2\x86\xb3 app/controllers/admin/albums_controller.rb:40:in `update'\n  Image Create (41.2ms)  INSERT INTO `images` (`file_name`, `title`, `alt`, `author`, `copyright`, `created_at`, `updated_at`) VALUES (NULL, NULL, NULL, NULL, NULL, '2022-05-20 09:18:46', '2022-05-20 09:18:46')\n  \xe2\x86\xb3 app/controllers/admin/albums_controller.rb:40:in `update'\n  AlbumImage Create (0.2ms)  INSERT INTO `album_images` (`album_id`, `image_id`, `created_at`, `updated_at`) VALUES (38, 231, '2022-05-20 09:18:46', '2022-05-20 09:18:46')\n  \xe2\x86\xb3 app/controllers/admin/albums_controller.rb:40:in `update'\n  Image Create (0.3ms)  INSERT INTO `images` (`file_name`, `title`, `alt`, `author`, `copyright`, `created_at`, `updated_at`) VALUES ('some-image.jpg', NULL, NULL, 'Some Author', 'SomeCopyRight', '2022-05-20 09:18:46', '2022-05-20 09:18:46')\n  \xe2\x86\xb3 app/controllers/admin/albums_controller.rb:40:in `update'\n  ImageFund Create (0.3ms)  INSERT INTO `image_funds` (`image_id`, `fund_id`, `created_at`, `updated_at`) VALUES (232, 1, '2022-05-20 09:18:46', '2022-05-20 09:18:46')\n  \xe2\x86\xb3 app/controllers/admin/albums_controller.rb:40:in `update'\n  ImageFund Create (0.2ms)  INSERT INTO `image_funds` (`image_id`, `fund_id`, `created_at`, `updated_at`) VALUES (232, 6, '2022-05-20 09:18:46', '2022-05-20 09:18:46')\n  \xe2\x86\xb3 app/controllers/admin/albums_controller.rb:40:in `update'\n  AlbumImage Create (0.3ms)  INSERT INTO `album_images` (`album_id`, `image_id`, `created_at`, `updated_at`) VALUES (38, 232, '2022-05-20 09:18:46', '2022-05-20 09:18:46')\n  \xe2\x86\xb3 app/controllers/admin/albums_controller.rb:40:in `update'\n  TRANSACTION (3.1ms)  COMMIT\n  \xe2\x86\xb3 app/controllers/admin/albums_controller.rb:40:in `update'\nRedirected to http://localhost:3000/admin/albums/38\nCompleted 302 Found in 2136ms (ActiveRecord: 52.4ms | Allocations: 46882)\n
Run Code Online (Sandbox Code Playgroud)\n

这是我的表格:

\n
<%= form_for [:admin, @album], html: {role: 'form' } do |f| %>\n  <%= render 'shared/error_messages', object: f.object %>\n  <%= f.fields_for :images, Image.new do |ff| %>\n    <div class='form-data'>\n      <%= ff.label :file_name, class: 'form-label' %>\n      <%= ff.file_field :file_name, multiple: :true, name: "album[images_attributes][][file_name]", class: 'form-field' %>\n    </div>\n    <div class="form-data">\n      <%= ff.label :author, class: "form-label" %>\n      <%= ff.text_field :author, name: "album[images_attributes][][author]", class: "form-field" %>\n    </div>\n    <div class="form-data">\n      <%= ff.label :copyright, class: "form-label" %>\n      <%= ff.text_field :copyright, name: "album[images_attributes][][copyright]", class: "form-field" %>\n    </div>\n    <div class="form-data">\n      <%= ff.label :fund, class: "form-label" %>\n      <% Fund.all.each do |fund| %>\n        <%= check_box_tag "album[images_attributes][][funds_ids][]", fund.id, ff.object.funds.include?(fund), class: "checkbox" %>\n        <%= fund.name %>\n      <% end %>\n    </div>\n  <% end %>\n  <div class='actions create'>\n    <%= f.submit 'Save' %>\n  </div>\n<% end %>\n
Run Code Online (Sandbox Code Playgroud)\n

为什么 images_attributes 得到一个包含两个元素的数组,而不是只有一个元素?

\n

我希望有人能让我走上正确的方向。预先非常感谢您!

\n

在相册控制器中,我设置了图像允许的参数:\nprivate

\n
def album_params\n  params.require(:album).permit(:title, :section_id, images_attributes: [:alt, :author, :copyright, :file_name, :title, funds_ids: []])\nend\n
Run Code Online (Sandbox Code Playgroud)\n

che*_*dli 6

太长了;设置它config/application.rb,它将解决您所有的文件字段问题。

config.active_storage.multiple_file_field_include_hidden = false
# or this, but beware of load order, you can probably put this in an initializer ( untested)
 ActionView::Helpers::FormHelper.multiple_file_field_include_hidden = false 
Run Code Online (Sandbox Code Playgroud)

Rails 7 中引入了新的配置选项ActionView::Helpers::FormHelper

默认情况下它是错误的。它在这里用在#field_field

然而,rails 7 中的 ActiveStorage默认情况下将其覆盖为 true ,特别是如果您config.load_defaults 7.0因为处理空集合的新功能而设置,请参见。

因此,您可以在 activestorage 配置上或直接在 FormHelper 类上include_hidden: false设置它,而不是添加所有文件字段,特别是如果您有一个大型应用程序。mattr_accessor


SEJ*_*EJU 5

我能够让它运行。include_hidden: false我需要在 file_field 中设置

<%= image.file_field :file_name, include_hidden: false, multiple: :true, name: "album[images_attributes][][file_name]", class: 'form-field' %>
Run Code Online (Sandbox Code Playgroud)

在更新 Rails 和 Carrierwave 之前,这在没有此选项的情况下也可以工作。