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:
- directly through Images
- 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 >
<%= ff.label :author, class: "form-label" %>
<%= ff.text_field :author, name: "album[images_attributes][][author]", class: "form-field" %>
</div>
<div >
<%= ff.label :copyright, class: "form-label" %>
<%= ff.text_field :copyright, name: "album[images_attributes][][copyright]", class: "form-field" %>
</div>
<div >
<%= 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
CodePudding user response:
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.