質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.12%

dropzone.js ファイルがDBに保存されない ruby on rails 5.1.0

受付中

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,320

ArthurLawrence

score 15

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では説明されていましたが、解決方法はまだいまいちわかっていません。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+1

dropzonejs-railsのインストール後に、application.js/application.scssへの追記は行いましたか?(README

// application.js
//= require dropzone

/* application.scss */
*= require dropzone/dropzone

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/05/22 16:20

    はい、その記述はしています。追加で書いておきます。

    キャンセル

+1

とりあえず、Rails5.1.0からJSライブラリの
考え方が刷新します。(正確にはRails5.0.0からなんですが)

dropzonejs-rails
等js名+arilsで管理されているものは
5.0までしかアップデートする気がないように思います。
現状、dropzonejs-railsはrails5.0.1までです。
なので、Rails5.1での動作は無保証です。

今後、javascriptライブラリはYarn経由で
webpackerというgemを利用して管理されますので(これすら確定事項でない)
dropzoneはYarnに対応しているので
rails webpacker:install:dropzone
等とやって、インストールしてください。
とりあえず、現在、5.1に対して包括的に説明した日本語のサイトがないので
私も、恥ずかしながらキャッチアップ仕切れていない状況ですorz
自信がないなら、rails5.0.2にダウングレードするのも手かもしれません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

見た感じjQueryが適用されていないのが原因ではないかな?と思います。

rails5.1.0からはjQueryが自動でインストールされない(Optionalに変更された)ため、rails new時にオプション指定してインストールするか、gemファイルにjquery-railsを追記してインストールするか、jQuery本体をダウンロードして配置するかする必要があると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/05/30 18:31

    ありがとうございます。 jquery-rails はインストール済みです。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.12%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる