I am trying to implement Dropzone.js as a Drag and drop profile photo uploader for the User scaffold
In my ruby on rails I've created user scaffold, that has a profile photo (the implementation is handled by PaperClip).
I want to create an experience that
- A User edits all details on the same page (including profile photo)
- On the first load of the edit/user/x page the current image is loaded;
- When the user has dropped the image over the form section, the image is rendered as a preview.
- If you click cancel, your previous image will be restored.
The approach I have come up with is to create a temp Uploads table that stores all images/files that are dropped into Dropzone. Upon successful upload, it will return the id of the image to the form, and then once the user clicks save, the id of the image will be posted with the form, and a link between the User and the Image will be created.
I have 2 questions for the stack overflow community:
- Am I overcomplicating this approach?
- I am getting the following error:
ActionController::ParameterMissing (param is missing or the value is empty: Upload):What have I done Wrong?
The code I have so far is outlined below.
Any help is appreciated.
<%= form_with(model: user, local: true) do |form| %>
<div class="form-group">
<% if user.errors.any? %>
<div id="error_explanation" class="row">
<h2><%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% user.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :name %>
<%= form.text_field :name, id: :user_name, :class=> "form-control" %>
</div>
<div id="profile-photo" class="field dropzone">
<%= form.file_field :profile, :class=> "fallback"%>
</div>
<div class="field">
<%= form.label :role %>
<%= form.text_field :role, id: :user_role, :class=> "form-control" %>
</div>
<div class="actions">
<%= form.submit %>
</div>
</div>
<% end %>
I have the following JavaScript
$("#profile-photo").dropzone({
url: '/uploads/upload',
maxFiles: 1,
maxfilesexceeded: function(file) {
this.removeAllFiles();
this.addFile(file);
},
success: function(file, response){
alert("upload was successful");
}
});
The following Controller#Action
# POST /uploads
# POST /uploads.json
def upload
puts request.request_parameters
@upload = Upload.new(upload_params)
if @upload.save
puts @upload.id
# format.html { redirect_to @upload, notice: @upload.id }
# format.json { render :show, status: :created, location: @upload }
else
# format.html { render :new }
# format.json { render json: @upload.errors, status: :unprocessable_entity }
end
end
def upload_params
params.require(:Upload).permit(:photo)
end
My request.request_parameters looks like the following:
Parameters: {"file"=>#<ActionDispatch::Http::UploadedFile:0x007f8fe120b278 @tempfile=#<Tempfile:/var/folders/rp/79zzx36504z9kp7srj55pxk80000gn/T/RackMultipart20170804-3814-13pid57.jpg>, @original_filename="tokyo.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"file\"; filename=\"tokyo.jpg\"\r\nContent-Type: image/jpeg\r\n">}