我有1个使用dropzone gem的表单,我想要实现的是 我希望将我的图像上传到一个具有1对多关系的表单中,我一直在努力让它无法运行。
这是我的数据库结构:
套间:
id
name
desc
unitplan:
id
unitplanphoto
apartement_id
公寓有很多单位计划,而单位计划只属于1个单位,
<div class="container-fluid">
<div class="animated fadeIn">
<!--/.row-->
<div class="row">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<strong>Apartement Form</strong>
</div>
<%= form_for @apt, html: {class: "form-horizontal", :multipart=>true} do |f| %>
<div class="card-block">
<div class="form-group row">
<%= f.label 'Apartement Name', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= f.text_field :apt_name, class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Apartement Address', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= f.text_area :apt_address, rows: 5, cols: 46 , class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Latitude', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= f.text_field :apt_lat, class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Longtitude', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= f.text_field :apt_long, class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Thumbnail', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= f.file_field :thumbnail, accept: 'image/jpeg,image/gif,image/png' %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Appartement Description', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= f.text_area :apt_desc, rows: 5, cols: 46 , class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Developer', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= collection_select(:apt, :developer_id, @developers, :id, :devname, {:prompt => false}, class: "form-control") %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Area', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= collection_select(:apt, :area_id, @areas, :id, :area_desc, {:prompt => false}, class: "form-control") %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Status', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= f.select :apt_status, options_for_select(@apt_statuses.collect { |s| [s[0].humanize, s[0]] }, selected: @apt.apt_status), {} , class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Facility', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= collection_check_boxes(:apt, :facility_ids, @facilities, :id, :facility_desc) %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Point of Interest', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= collection_check_boxes(:apt, :poi_ids, @pois, :id, :poi_name) %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Floor plan photos', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= file_field_tag "images[]", type: :file, multiple: true %>
</div>
</div>
<% end %>
<div class="form-group row">
<div class="col-md-8">
<input id="unitplans_ids" name="unitplans_ids" type="hidden" value="">
<!--<input data-url="/photos" id="unitplans_upload" multiple="multiple" name="unitplans[]" type="file" ></input>-->
<!--<form action="/unitplans/create" id="dzCover" method="post" enctype="multipart/form-data" class="dropzone">-->
<%= form_for @unitplan, html: {class: "dropzone", :multipart=>true, id: "dzCover"} do |f| %>
<div id="actionsCover" class="row">
<div class="col-lg-8">
<label for="image">Unit plan photos : </label>
<!-- The fileinput-button span is used to style the file input field as button -->
<span class="btn btn-success fileinput-button2">
<i class="glyphicon glyphicon-plus"></i>
<span>Add files...</span>
</span>
<button type="button" class="btn btn-primary start">
<i class="glyphicon glyphicon-upload"></i>
<span>Start upload</span>
</button>
<button type="button" class="btn btn-warning cancel">
<i class="glyphicon glyphicon-ban-circle"></i>
<span>Cancel upload</span>
</button>
</div>
<div class="col-lg-5">
<!-- The global file processing state -->
<span class="fileupload-process">
<div id="total-progress" class="progress progress-striped active" style="display:none" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">
<div class="progress-bar progress-bar-success" style="width:0%;" data-dz-uploadprogress></div>
</div>
</span>
</div>
</div>
<div class="form-group">
<!-- HTML heavily inspired by http://blueimp.github.io/jQuery-File-Upload/ -->
<div class="table table-striped" class="files" id="previewsCover">
<div id="templateCover" class="file-row">
<!-- This is used as the file preview template -->
<div>
<span class="preview"><img data-dz-thumbnail /></span>
</div>
<div>
<p class="name" data-dz-name></p>
<strong class="error text-danger" data-dz-errormessage></strong>
</div>
<div>
<p class="size" data-dz-size></p>
<div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">
<div class="progress-bar progress-bar-success" style="width:0%;" data-dz-uploadprogress></div>
</div>
</div>
<div>
<button type="button" class="btn btn-primary start">
<i class="glyphicon glyphicon-upload"></i>
<span>Start</span>
</button>
<button type="button" data-dz-remove class="btn btn-warning cancel">
<i class="glyphicon glyphicon-ban-circle"></i>
<span>Cancel</span>
</button>
<button type="button" data-dz-remove class="btn btn-danger delete">
<i class="glyphicon glyphicon-trash"></i>
<span>Delete</span>
</button>
</div>
</div>
</div>
<br>
</div>
<!-- </form>-->
<% end %>
</div>
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-sm btn-primary"><i class="fa fa-dot-circle-o"></i> Submit</button>
</div>
</div>
</div>
<!--/col-->
</div>
<!--/.row-->
</div>
</div>
我的js文件:
$( document ).ready(function()
{
var previewNode1 = document.querySelector("#templateCover");
console.log(previewNode1);
console.log(previewNode1.id);
previewNode1.id = "";
var previewTemplate1 = previewNode1.parentNode.innerHTML;
previewNode1.parentNode.removeChild(previewNode1);
var myDropzoneCover = new Dropzone("#dzCover", { // Make the whole body a dropzone
url: "/unitplans/create", // Set the url
thumbnailWidth: 80,
thumbnailHeight: 80,
parallelUploads: 20,
paramName: "unitplanphoto",
previewTemplate: previewTemplate1,
autoQueue: false, // Make sure the files aren't queued until manually added
previewsContainer: "#previewsCover", // Define the container to display the previews
clickable: ".fileinput-button2", // Define the element that should be used as click trigger to select files.
maxFilesize: 5,
acceptedFiles: ".png, .jpg, .jpeg", //is this correct? I got an error if im using this
init: function() {
this.on("success", function(file, response)
{
console.log(response);
file.serverId = response;
//alert(response);
});
this.on("removedfile", function(file)
{
//console.log(file);
//console.log(file.serverId);
if (!file.serverId)
{
return;
}
else
$.post("/unitplans/destroy?id=" + file.serverId);
});
this.options.previewaDropzone = false;
}
});
myDropzoneCover.on("addedfile", function(file) {
// Hookup the start button
file.previewElement.querySelector("#previewsCover .start").onclick = function() { myDropzoneCover.enqueueFile(file); };
//console.log(file);
});
// Update the total progress bar
myDropzoneCover.on("totaluploadprogress", function(progress) {
document.querySelector("#actionsCover #total-progress .progress-bar").style.width = progress + "%";
});
myDropzoneCover.on("sending", function(file) {
// Show the total progress bar when upload starts
document.querySelector("#actionsCover #total-progress").style.opacity = "1";
// And disable the start button
file.previewElement.querySelector("#previewsCover .start").setAttribute("disabled", "disabled");
//alert("sending");
});
// Hide the total progress bar when nothing's uploading anymore
myDropzoneCover.on("queuecomplete", function(progress) {
document.querySelector("#actionsCover #total-progress").style.opacity = "0";
//alert("complete");
});
// Setup the buttons for all transfers
// The "add files" button doesn't need to be setup because the config
// `clickable` has already been specified.
document.querySelector("#actionsCover .start").onclick = function() {
myDropzoneCover.enqueueFiles(myDropzoneCover.getFilesWithStatus(Dropzone.ADDED));
};
document.querySelector("#actionsCover .cancel").onclick = function() {
myDropzoneCover.removeAllFiles(true);
};
} );
控制器文件:
class UnitplansController < ApplicationController
def create
@unitplan = Unitplan.new(unitplan_params)
#respond_to do |format|
if @unitplan.save
render json: {message: "sukses", unitplanID: @unitplan.id}, status: 200
else
render json: { error: @unitplan.errors.full_messages.join(", ") }, status: 400
end
end
private
def unitplan_params
params.require(:unitplan).permit(:unitplanphoto)
end
end
某种程度上我不能让它工作,如果我点击提交后检查dropzone请求,它总是抛出这个错误:
ActionController::ParameterMissing in UnitplansController#create
param is missing or the value is empty: unitplan
答案 0 :(得分:2)
您的params
似乎错过了unitplan
方法所需的unitplan_params
密钥。
尝试将js文件中的paramName
值更改为:
paramName: "unitplan[unitplanphoto]",
unitplan_params
充当params的白名单,以确保您只将已批准的参数传递给您的控制器方法,因此您需要确保您的传入参数符合require
和permit
规则