简体   繁体   中英

Rails 5: multipart field inside a nested form doesn't work

I'm using the carrierwave gem in order to upload files. I have a form with one nested_form field from where I'm trying to upload multiple files. But for some odd reason the multipart=true doesn't work when I try to upload multiple files. I get this error: Validation failed: Attachments media files can't be blank and in the console I get an Unpermitted parameter: :media_files ....even thought the params seem to pass when the form is submitted:

Started POST "/item/create" for 127.0.0.1 at 2018-10-23 13:08:19 +0300
Processing by ItemsController#create as HTML
Parameters: {"utf8"=>"✓","authenticity_token"=>
"tDpyPV9fPxLUHgRVb4G6P3eMLFUv0hKVnNPJCAcgYISCwjIbjA5bu/iXOy0k6yL
8+QWXs3MyoJ3lzzyhj3rqkw==", "item"=>{"title"=>"Sample",  "description"
=>"Lorem", "attachments_attributes"=>{"0"=>{"media_files"=>[#
<ActionDispatch::Http::UploadedFile:0x007fe818a5ecb0 @tempfile=# 
<Tempfile:/var/folders/hq/pr4rt14n7s31v3f6292wtjm00000gn/T/
RackMultipart20181023-1573-1r65sf9.jpg>, @original_filename=
"image1.jpg", @content_type="image/jpeg", @headers="Content- 
Disposition: form-data; name=\"item[attachments_attributes]
[0][media_files][]\"; filename=\"image1.jpg\"\r\nContent-Type: 
image/jpeg\r\n">, #<ActionDispatch::Http::UploadedFile
:0x007fe818a5ebe8 @tempfile=#
<Tempfile:/var/folders/hq/pr4rt14n7s31v3f6292wtjm00000gn
/T/RackMultipart20181023-1573-1lbr709.jpg>,  
@original_filename="image2.jpg", @content_type=
"image/jpeg", @headers="Content-Disposition: form-data;  
name=\"item[attachments_attributes][0][media_files][]\";  
filename=\"image2.jpg\"\r\nContent-Type: image/jpeg\r\n">], "item_id"=>"# 
<Item:0x007fe813ef65e8>"}}}, "commit"=>"Create"}

Unpermitted parameter: :media_files

This is nested_form setup I have:

  create_table "attachments", force: :cascade do |t|
  t.integer "item_id"
  t.string "media_files"
  t.string "content_type"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

class Item < ApplicationRecord
  has_many :attachments, dependent: :destroy
  accepts_nested_attributes_for :attachments, allow_destroy: true
end

class Attachment < ApplicationRecord
  belongs_to :item
  mount_uploader :media_files, AttachmentUploader
  validates_presence_of :media_files
end

This is the attachments_controller.rb method:

def create
  params["item"]["attachments_attributes"]["0"]["media_files"].each { |file| @attachment = Attachment.new(:media_files => file)}

  respond_to do |format|
    if @attachment.save
      format.html { redirect_back fallback_location: root_path, notice: 'Attachment was successfully created.' }
      format.json { render :'shows/show', status: :created, location: @attachment }
    else
      format.html { render :new }
      format.json { render json: @attachment.errors, status: :unprocessable_entity }
    end
  end
end

and the nested params inside the items_controller.rb :

params.require(:item).permit(:title, :description, attachments_attributes: [:media_files, :item_id, :content_type])

The form with the nested field:

<%= form_for(@item, url: items_create_path, :html => { :multipart => true }) do |form| %>
<%= form.text_field :title, id: :item_title, autofocus: true, :class=>"form-control" %>
    <%= form.text_area :description, id: :item_description, :class=>"form-control" %>

  <%= form.fields_for :attachments do |f| %>
      <div class="form-group">
  <%= f.file_field :media_files, multiple: true, :id=>"upload-photo" %>
  <% end %>

  <%= form.submit "Create", :class=>"btn btn-default" %>
  <% end %>

Any ideas on how to make this work?

Unpermitted parameter: :media_files

Means the parameter "media_files", which you use in the following line has not been permitted:

params["item"]["attachments_attributes"]["0"]["media_files"].each { |file| @attachment = Attachment.new(:media_files => file)}

This line itself is quite strange, as you're iterating on the parameters to instantiate a new Attachment each time oO

This line is almost OK, just change the attachments_attributes :

params.require(:item).permit(:title, :description, attachments_attributes: [:item_id, :content_type, :media_files => []])

But that's what you have to give to Item.new , as your form points to items_create_path .

Why do you expect it to reach attachments_controller.rb ?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM