Reputation: 932
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
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
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
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