Bradley
Bradley

Reputation: 932

Rails 4 | Unpermitted parameter: images when using Paperclip to upload multiple images using Paperclip form

Struggling with strong parameters when using simple-form to upload multiple images from paperclip in my form. I'm constantly getting an error popping up on the server

"Unpermitted parameters: images"

When the form tries to upload into the Database. Ok so here's what I've got so far.

Form code:

<%= f.input :images, as: :file, input_html: { multiple: true } %>

Desks Controller:

def new
    @desk = current_user.desks.build

    @desk.office_type_id = params[:office_type_id]
    @desk.desk_type_id = params[:desk_type_id]

    @amenities = Amenity.all
    @desk.amenity_ids = params[:amenities]

end

def create
    @desk = current_user.desks.build(desk_params)


    if @desk.save

        if params[:images]
            params[:images].each do |image|
                @desk.photos.create(image: image)
            end
        end

        @photos = @desk.photos
        redirect_to edit_desk_path(@desk), notice: "Saved..."
    else
        render "new"
    end
end


private
    def set_desk
        @desk = Desk.find(params[:id])
    end

def desk_params
    params.require(:desk).permit(:office_type_id, :desk_type_id, 
        :office_type, :desk_type, :listing_name, :min_days, :max_days, 
        :accommodate, :daily_rate, :location, :description, :amenities, 
        amenity_ids: [], 
        :photos_attributes => [ :images ])
end

I have a photos model:

class Photo < ActiveRecord::Base
    belongs_to :desk

    has_attached_file :image, styles: { medium: "300x300>", thumb: "100x100>" }
    validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/
end

Desk Model:

    has_many :photos

I have tried whitelisting just .., :images , and .., :images => [] ,

Neither successful. I'm sure I've tried other combinations that will allow an array into the mix.

One point worth noting is the server code example of multiple images upload is showing an array being pulled into the parameters. Example:

Processing by DesksController#update as HTML


 Parameters: {"utf8"=>"✓", "authenticity_token"=>"hgEIE6yirx7ixY8Xs0mUxA+6G3wmy/D4wKSLKrF+clTfzvpunFG11PmEfI2l3bPV0IlCywdmvajshMph7c5V+A==", "desk"=>{"office_type_id"=>"1", "desk_type_id"=>"1", "accommodate"=>"1", "min_days"=>"1", "max_days"=>"2", "listing_name"=>"1111", "description"=>"111", "location"=>"111", "daily_rate"=>"100", "amenity_ids"=>["2", "3", ""], "images"=>[#<ActionDispatch::Http::UploadedFile:0x007fba71ce2880 @tempfile=#<Tempfile:/var/folders/gx/86yj74bx3md88cfn2fwc975h0000gn/T/RackMultipart20170713-20588-1bin85a.JPG>, @original_filename="IMG_1420.JPG", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"desk[images][]\"; filename=\"IMG_1420.JPG\"\r\nContent-Type: image/jpeg\r\n">, #<ActionDispatch::Http::UploadedFile:0x007fba71ce2268 @tempfile=#<Tempfile:/var/folders/gx/86yj74bx3md88cfn2fwc975h0000gn/T/RackMultipart20170713-20588-1ac6bwu.JPG>, @original_filename="IMG_1421.JPG", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"desk[images][]\"; filename=\"IMG_1421.JPG\"\r\nContent-Type: image/jpeg\r\n">]}, "commit"=>"Update Desk", "id"=>"37"}

This has been very frustrating. Would appreciate any help or guidance to what is going on here. I was sure it may be a nesting issue but still cant get it to work with the current code. Thanks a mil.

Upvotes: 1

Views: 1102

Answers (3)

Bradley
Bradley

Reputation: 932

Ok so I eventually figured out what the issue was here from the help of @irldexter and @pavan. They made suggestions that were not quite right but definitely helped me to figure out the issue in the end. I've added it an an answer to keep it all together.

So the issue I noticed when I looked into both how rails_form and simple_form where sending the parameters across was that the html name in the header was different on each. I also noticed that because of this simple_form was including the images in my desk=>{} and not separating it out into its own array.

Simple-form (Not working)

Parameters: {"utf8"=>"✓", 
"authenticity_token"=>"1c3dbJYJWuPs3L95F2eqkxm8Fuwr5J3D5LdEyRLeS7sAYgnbhEBIcfsE1A4Hw2rQy8zbZEdr6mMcZTjUGH3Cpg==", 
"desk"=>{"listing_name"=>"Dublin Desk Image", 
"description"=>"Desk in Dublin", 
"accommodate"=>"1", 
"price"=>"100", 

"images"=>#<ActionDispatch::Http::UploadedFile:0x007fce7cf618d0 @tempfile=#<Tempfile:/var/folders/gx/86yj74bx3md88cfn2fwc975h0000gn/T/RackMultipart20170718-1255-luxbhv.JPG>,
@original_filename="IMG_1421.JPG", 
@content_type="image/jpeg", 
@headers="Content-Disposition: form-data; name=\"desk[images]\"; 
filename=\"IMG_1421.JPG\"\r\nContent-Type: image/jpeg\r\n">},

 "commit"=>"Create Desk"

Rails form (Working)

    Parameters: {"utf8"=>"✓", 
"authenticity_token"=>"8YqUPPx9qumESGiSjkZCtxunFPsdeFed+pXmamWKwmY8jfwRXXCNDTUSJOdfT9R2b13NLOOGyqo3gOiP8FE08Q==", 

"office"=>{
"office_type"=>"Private", "desk_type"=>"Corporate", "accommodates"=>"2", "min_hours"=>"3", "max_hours"=>"2", "listing_name"=>"image test", "summary"=>"rgerg", "address"=>"grafton street, dublin 1", "is_aircon"=>"1", "is_elevator"=>"0", "is_showers"=>"0", "is_changing_room"=>"0", "is_printer"=>"1", "is_kitchen"=>"0", "is_telephone"=>"0", "is_desktop_computer"=>"0", "is_coffee_machine"=>"0", "is_meeting_room"=>"0", "is_wifi"=>"0", "price"=>"123", "active"=>"1"}, 

"images"=>[#<ActionDispatch::Http::UploadedFile:0x007fbeef60fa08 @tempfile=#<Tempfile:/var/folders/wj/p88yb82j39x40kgcm1qg24g00000gn/T/RackMultipart20170718-96629-11meflg.jpg>, @original_filename="benjamin-child-17946.jpg", 
@content_type="image/jpeg", 
@headers="Content-Disposition: form-data; name=\"images[]\"; 
filename=\"benjamin-child-17946.jpg\"\r\nContent-Type: image/jpeg\r\n">], 

"commit"=>"Save"}

simple form stuff was simplified when i recreated the problem. I needed to change the name= somehow in the simpleform code. It was as easy as this when I realised the problem.

<%= f.input :images, as: :file, input_html: { name: 'images[]' } %>

Strong parameters where ok with just calling

    def desk_params
        params.require(:desk).permit(:listing_name, :description, :accommodate, :price, :active, :images)
    end

I also noticed there must have been some issue with the params not being found because the code was running the

if params[:images]
        params[:images].each do |image|
            @desk.photos.create(image: image)
        end
    end

code when I added in put messages to see if it was returning a true value. I've also added in the Desk model

accepts_nested_attributes_for :photos

As easy as the fix was in the end it was only because of the mentioning of network headers and possibly the use of f.input_field in simple form which removes any form wrappers and also the name: change method. Thanks @pavan @irldexter for the help and advice. It helped me learn more about the actual form data that is sent. Much respect.

Upvotes: 1

Pavan
Pavan

Reputation: 33542

Unpermitted parameters: images

When you look at the params hash, you don't have photos_attributes key. The images: [] come directly inside the desk. So you need to modify the desk_params to below

def desk_params
  params.require(:desk).permit(:office_type_id, :desk_type_id, 
  :office_type, :desk_type, :listing_name, :min_days, :max_days, 
  :accommodate, :daily_rate, :location, :description, :amenities, 
  amenity_ids: [], images: [])
end

Upvotes: 0

irldexter
irldexter

Reputation: 11

Desk Model should include something that permits it to create photos objects like:

has_many :photos
accepts_nested_attributes_for :photos

and Desk Controller should include not just the potential for an array of photo ids but also the specific attributes required to create one, the default of which is an id and then an image which is the attachment:

def desk_params
    params.require(:desk).permit(:office_type_id, :desk_type_id, 
        :office_type, :desk_type, :listing_name, :min_days, :max_days, 
        :accommodate, :daily_rate, :location, :description, :amenities, 
        amenity_ids: [], photo_ids: [], photo_attributes: [ :id, :image ])
end

I would use the param param[:photo_ids] in the view/controller logic rather than images on desk to avoid confusion and map the relationship.

Also, recommend you see what the development log spits out in terms of un-permitted parameters and also look at the params in your browser console to see exactly what is try to be posted.

In your rails console (as I can not see your schema, perhaps output):

Desk.column_names

and

Photo.column_names

to confirm your params and also check the model/schema for which are required and can not be null (and don't have defaults if null => false)

Upvotes: 0

Related Questions