铁轨:多文件上传产生一个空的条目

发布于 2025-01-31 04:21:23 字数 5633 浏览 4 评论 0 原文

我正在尝试创建某种嵌套的文件上传。我有图像和专辑,它们通过模型蛋白映像相关。图像可以成为专辑的一部分。上传是通过载波进行的。

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

  1. 直接通过图像
  2. 通过相册

通过相册上传,应该将它们上传并插入图像和蛋白映像表中。

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

Started PATCH "/admin/albums/38" for ::1 at 2022-05-20 11:18:44 +0200
Processing by Admin::AlbumsController#update as HTML
  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"}
  Admin Load (0.3ms)  SELECT `admins`.* FROM `admins` WHERE `admins`.`id` = 1 ORDER BY `admins`.`id` ASC LIMIT 1
  Album Load (0.2ms)  SELECT `albums`.* FROM `albums` WHERE `albums`.`id` = 38 LIMIT 1
  ↳ app/controllers/admin/albums_controller.rb:39:in `update'
  TRANSACTION (0.2ms)  BEGIN
  ↳ app/controllers/admin/albums_controller.rb:40:in `update'
  Fund Load (0.5ms)  SELECT `funds`.* FROM `funds` WHERE `funds`.`id` IN (1, 6)
  ↳ app/controllers/admin/albums_controller.rb:40:in `update'
  Section Load (0.3ms)  SELECT `sections`.* FROM `sections` WHERE `sections`.`id` = 5 LIMIT 1
  ↳ app/controllers/admin/albums_controller.rb:40:in `update'
  Fund Exists? (0.3ms)  SELECT 1 AS one FROM `funds` WHERE `funds`.`name` = 'SomeFundA' AND `funds`.`id` != 1 LIMIT 1
  ↳ app/controllers/admin/albums_controller.rb:40:in `update'
  Fund Exists? (0.2ms)  SELECT 1 AS one FROM `funds` WHERE `funds`.`name` = 'SomeFundB' AND `funds`.`id` != 6 LIMIT 1
  ↳ app/controllers/admin/albums_controller.rb:40:in `update'
  Album Exists? (0.2ms)  SELECT 1 AS one FROM `albums` WHERE `albums`.`title` = 'SomeAlbum' AND `albums`.`id` != 38 LIMIT 1
  ↳ app/controllers/admin/albums_controller.rb:40:in `update'
  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')
  ↳ app/controllers/admin/albums_controller.rb:40:in `update'
  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')
  ↳ app/controllers/admin/albums_controller.rb:40:in `update'
  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')
  ↳ app/controllers/admin/albums_controller.rb:40:in `update'
  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')
  ↳ app/controllers/admin/albums_controller.rb:40:in `update'
  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')
  ↳ app/controllers/admin/albums_controller.rb:40:in `update'
  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')
  ↳ app/controllers/admin/albums_controller.rb:40:in `update'
  TRANSACTION (3.1ms)  COMMIT
  ↳ app/controllers/admin/albums_controller.rb:40:in `update'
Redirected to http://localhost:3000/admin/albums/38
Completed 302 Found in 2136ms (ActiveRecord: 52.4ms | Allocations: 46882)

这是我的形式:

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

为什么images_attributes获得两个元素的数组,而不仅仅是一个元素?

我希望有人可以把我朝正确的方向发展。非常感谢您!

在专辑控制器中,我为图像设置了允许的参数: 私人的

def album_params
  params.require(:album).permit(:title, :section_id, images_attributes: [:alt, :author, :copyright, :file_name, :title, funds_ids: []])
end

I am trying to create some sort of a nested file upload. I have Images and Albums, which are related through the model AlbumImages. Images can be part of an album. The upload is carried out through Carrierwave.

I want to be able to upload Images in two ways:

  1. directly through Images
  2. through Albums

When uploading Images through Albums they should be uploaded and inserted into the Images and AlbumImages tables.

I can upload single images through Images, but to my surprise, my current implementation for uploading multiple images through Albums results in 2 separate data entries. (This used to work under Rails 3) The first entry is empty and the second is the one I am aiming for.

Started PATCH "/admin/albums/38" for ::1 at 2022-05-20 11:18:44 +0200
Processing by Admin::AlbumsController#update as HTML
  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"}
  Admin Load (0.3ms)  SELECT `admins`.* FROM `admins` WHERE `admins`.`id` = 1 ORDER BY `admins`.`id` ASC LIMIT 1
  Album Load (0.2ms)  SELECT `albums`.* FROM `albums` WHERE `albums`.`id` = 38 LIMIT 1
  ↳ app/controllers/admin/albums_controller.rb:39:in `update'
  TRANSACTION (0.2ms)  BEGIN
  ↳ app/controllers/admin/albums_controller.rb:40:in `update'
  Fund Load (0.5ms)  SELECT `funds`.* FROM `funds` WHERE `funds`.`id` IN (1, 6)
  ↳ app/controllers/admin/albums_controller.rb:40:in `update'
  Section Load (0.3ms)  SELECT `sections`.* FROM `sections` WHERE `sections`.`id` = 5 LIMIT 1
  ↳ app/controllers/admin/albums_controller.rb:40:in `update'
  Fund Exists? (0.3ms)  SELECT 1 AS one FROM `funds` WHERE `funds`.`name` = 'SomeFundA' AND `funds`.`id` != 1 LIMIT 1
  ↳ app/controllers/admin/albums_controller.rb:40:in `update'
  Fund Exists? (0.2ms)  SELECT 1 AS one FROM `funds` WHERE `funds`.`name` = 'SomeFundB' AND `funds`.`id` != 6 LIMIT 1
  ↳ app/controllers/admin/albums_controller.rb:40:in `update'
  Album Exists? (0.2ms)  SELECT 1 AS one FROM `albums` WHERE `albums`.`title` = 'SomeAlbum' AND `albums`.`id` != 38 LIMIT 1
  ↳ app/controllers/admin/albums_controller.rb:40:in `update'
  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')
  ↳ app/controllers/admin/albums_controller.rb:40:in `update'
  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')
  ↳ app/controllers/admin/albums_controller.rb:40:in `update'
  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')
  ↳ app/controllers/admin/albums_controller.rb:40:in `update'
  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')
  ↳ app/controllers/admin/albums_controller.rb:40:in `update'
  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')
  ↳ app/controllers/admin/albums_controller.rb:40:in `update'
  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')
  ↳ app/controllers/admin/albums_controller.rb:40:in `update'
  TRANSACTION (3.1ms)  COMMIT
  ↳ app/controllers/admin/albums_controller.rb:40:in `update'
Redirected to http://localhost:3000/admin/albums/38
Completed 302 Found in 2136ms (ActiveRecord: 52.4ms | Allocations: 46882)

This is is my form:

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

Why does images_attributes get an array of two elements, instead of just one?

I hope someone can put me into the right direction. Thank you very much in advance!

In the Albums controller I set the permitted parameters for images:
private

def album_params
  params.require(:album).permit(:title, :section_id, images_attributes: [:alt, :author, :copyright, :file_name, :title, funds_ids: []])
end

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

猫七 2025-02-07 04:21:23

tldr;在 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 

在Rails 7上,新的配置选项已 ActionView :: helpers :: formhelper

默认情况下,它的false。它已被用于#field_field

However, ActiveStorage in rails 7 overrides it to true

因此,代码> include_hidden:false 在所有文件字段上,尤其是如果您有一个大应用程序,则可以在ActivEstorage Config上或直接在FormHelper类上设置此 mattr_accessor

TLDR; Set this in config/application.rb and it will solve all your file fields issues.

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 

On rails 7 a new configuration option has been introduced in ActionView::Helpers::FormHelper

By default it's false. and it's used here in #field_field

However, ActiveStorage in rails 7 overrides it to true by default, especially if you set config.load_defaults 7.0 because of a new feature to handle empty collections, cf.

So instead of adding include_hidden: false on ALL your file fields, especially if you have a big application, you can set this mattr_accessor either on activestorage config, or directly on the FormHelper class.

掩耳倾听 2025-02-07 04:21:23

我能够运行它。我需要在File_field中设置 inclage_hidden:false

<%= image.file_field :file_name, include_hidden: false, multiple: :true, name: "album[images_attributes][][file_name]", class: 'form-field' %>

然后更新导轨和载体波,用于无需此选项就可以使用。

I was able to get it running. I needed to set include_hidden: false in the file_field

<%= image.file_field :file_name, include_hidden: false, multiple: :true, name: "album[images_attributes][][file_name]", class: 'form-field' %>

Before updating Rails and Carrierwave this used to work without this option.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文