##dropzone.jsでuploadしてもうまくDBに保存されない
gem list
gem 'rails', '~> 5.1.0' gem 'sqlite3' gem 'puma', '~> 3.7' gem 'sass-rails', '~> 5.0' gem 'uglifier', '>= 1.3.0' gem 'coffee-rails', '~> 4.2' gem 'turbolinks', '~> 5' gem 'jbuilder', '~> 2.5' gem 'bootstrap-sass' gem 'autoprefixer-rails' gem 'devise' gem 'jquery-rails' gem 'jquery-ui-rails' gem 'toastr-rails' gem 'omniauth-facebook' gem "paperclip", "~> 5.0.0" gem 'dropzonejs-rails' gem 'jquery-turbolinks' group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] # Adds support for Capybara system testing and selenium driver gem 'capybara', '~> 2.13.0' gem 'selenium-webdriver' end group :development do # Access an IRB console on exception pages or by using <%= console %> anywhere in the code. gem 'web-console', '>= 3.3.0' gem 'listen', '>= 3.0.5', '< 3.2' # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring gem 'spring' gem 'spring-watcher-listen', '~> 2.0.0' end
html.erb
<%= render 'partial/navbar' %> <div class="container"> <div class="col-md-3"> <!-- vertical-navbar --> <%= render 'partial/verticalnavbar'%> </div> <div class="col-md-9"> <div class="panel panel-default"> <div class="panel-heading"> <div class="text-center"> <span style="font-size:24px;">リスティング写真の編集</span> </div> </div> <div class="panel-body"> <script type="text/javascript"> Dropzone.options.myDropzone = { addRemoveLinks: true, removedfile: function(file) { var _ref; return (_ref = file.previewElement) != null ? _ref.parentNode.removeChild(file.previewElement) : void 0; } }; </script> <%= form_for @photo, html:{multipart: true,class:"dropzone", id:"my-dropzone" } do |f| %> <%= f.hidden_field :listing_id, value: @listing.id %> <div class="dz-message needsclick"> <h3>ファイルをここにドロップしてください。</h3> <strong>アップロードするにはここをクリックしてください</strong> </div> <div class="fallback"> <%= f.file_field :image %> <%= f.submit "Upload image" %> </div> <% end %> </div> </div> </div> </div> <!-- dropzone.js --> <script type="text/javascript"> $(function () { Dropzone.autoDiscover = false; //photos_controller.rbのcreateアクションが呼ばれる $("#my-dropzone").dropzone({ maxFilesize: 200,// MB addRemoveLinks: true,//削除リンク,Cancelリンクを全てのpreviewファイルに付ける。 paramName: 'photo[image]',// パラメータの名前 success: function(file, response) { // file.previewElementでpreview要素のhtmlにアクセスできる //add .dz-success class to file.previewElement $(file.previewElement).addClass('dz-success'); //add response.uploadId to .dz-remove class $(file.previewElement).find('.dz-remove').attr('id', response.photoId); }, removedfile: function(file) { // 削除選択されたfileのidを取得 var id = $(file.previewTemplate).find('.dz-remove').attr('id'); //call photos_controler.rb destroy action $.ajax({ type: 'DELETE', url: "/photos/" + id, success: function(data) { console.log(data.message); } }); var previewElement; // 条件式 ? 式1 : 式2 条件式の値がtrue=>式1、false=>式2返します。 //parentNode => 親ノード(一つ上のhtml要素)を取得. //(void 0) => 何も処理しない // リスト(親ノード)から、プレビュー要素を消すという記述 return (previewElement = file.previewElement) != null ? (previewElement.parentNode.removeChild(file.previewElement)) : (void 0); }, // init executed at first when Page loaded init: function() { //this equal dropzone var me = this; //meに"complete"イベントを定義 me.on("complete", function(file) { $(file.previewTemplate).find('.dz-remove').text("削除する"); }); //call list function in photos_controller.rb with get method $.ajax({ type: "GET", url: "/photos/list", data: {'listing_id': <%= @listing.id %>}, dataType: 'json', success: function(data){ $.each(data.images, function(key, value) { if (data.images != undefined && data.images.length > 0) { me.emit("addedfile", value); //addedfileイベントをvalueのデータで実行する me.emit("thumbnail", value, value.src);//thumbnailイベントをvalueのデータで実行する me.emit("complete", value); //completeイベントをvalueのデータで実行する $(value._removeLink).attr("id", value.id); //valueの_removeLinkのidにvalue.idを追加 } }); } }); } }); }); </script>
application.scss
@import "bootstrap-sprockets"; @import "bootstrap"; @import "toastr"; @import "dropzone/dropzone";
photos_controller.rb
class PhotosController < ApplicationController def create @photo = Photo.new(photo_params) if @photo.save render json: {message: "success", photoId:@photo.id}, status: 200 else render json: { error:@photo.errors.full_messages.join(",")}, status:400 end end def destroy @photo = Photo.find(params[:id]) if @photo.destroy render json: { message: "file deleted from server"} else render json: {message: @photo.errors.full_messages.join(",")} end end def list listing = Listing.find(params[:listing_id]) photos = [] Photo.where(listing_id: listing.id).each do |photo| new_photo ={ id: photo.id, name: photo.image_file_name, size: photo.image_file_size, src: photo.image(:thumb) } photos.push(new_photo) end render json: {images:photos} end private def photo_params params.require(:photo).permit(:image,:listing_id) end end
クロムコンソールでは、jQueryにエラーがでていて、それが原因かなとも思っています。
エラー
Uncaught TypeError: $(...).dropzone is not a function at HTMLDocument.<anonymous> (photos:160) at j (jquery.min.js:2) at Object.fireWith [as resolveWith] (jquery.min.js:2) at Function.ready (jquery.min.js:2) at HTMLDocument.K (jquery.min.js:2)
Ruby on rails のパージョンの互換性の問題なのでしょうか?
上記のエラーは他のlibraryがjQueryに干渉しているために発生しているとStackoverflowでは説明されていましたが、解決方法はまだいまいちわかっていません。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。