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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

1回答

568閲覧

[Rails5]JavaScript側でのアップロードが完了してから、createアクションに移るようにしたい

tacro

総合スコア23

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

0クリップ

投稿2018/04/02 06:20

編集2018/04/02 08:25

前提・実現したいこと

Rails5を使って、ユーザーが画像を選択し、自由にトリミングした上で投稿できる機能を実装中です。

参考:[Javascript] Rails5でユーザーがトリミングした画像を、S3に直接アップロードしたい

画像のアップロードは問題なくできるのですが、アップした画像をviewで表示する際に問題が発生しています。

発生している問題・エラーメッセージ

画像を表示させようとすると、以下のようなエラーが出ます。

The asset "" is not present in the asset pipeline.

postオブジェクトの中身をのぞいてみると、image_nameの部分が、"#<ActionDispatch::Http::UploadedFile:0x00007fe3122..."になっています。
本来ならば、ここには、"//my-development.s3.amazonaws.com/uploads/...のような、s3上の画像を参照するURLを入れておきたいです。

画像をトリミング処理しない場合は、問題なくこのURLが入力され、表示できるのですが、トリミングを行うとこの値が渡されてしまいます。

デバックしてみたところ、以下のjavascriptコードの、fileUpload関数内のdoneコールバックが呼ばれていないようです。
どうすればこのコールバックがきちんと呼ばれるようになるか、アドバイスをお願いいたします。

【追記】s3へのアップロードが完了しないまま、ページが遷移してしまうことが原因のようです。submitボタンをクリックした際に、js側でs3へのアップロードを完了させたあとに、フォームをサーバーに提出させるには、どうすればいいでしょうか?
→**【追記2】formのsubmitを一度中断し、アップロード完了後に再開させるという処理を思いつきました。**中断はできるのですが、再開がうまくできません。「試したこと」欄に詳述するので、アドバイスいただきたいです。

該当のソースコード

javascript

1$(function() { 2 $('.directUpload').find("input:file").each(function(i, elem) { 3 var fileInput = $(elem); 4 var form = $(fileInput.parents('form:first')); 5 var submitButton = form.find('input[type="submit"]'); 6 var progressBar = $("<div class='bar'></div>"); 7 var barContainer = $("<div class='progress'></div>").append(progressBar); 8 fileInput.after(barContainer); 9 fileInput.fileupload({ 10 fileInput: fileInput, 11 url: form.data('url'), 12 type: 'POST', 13 autoUpload: false, 14 formData: form.data('form-data'), 15 paramName: 'file', // S3 does not like nested name fields i.e. name="user[avatar_url]" 16 dataType: 'XML', // S3 returns XML if success_action_status is set to 201 17 replaceFileInput: false, 18 acceptFileTypes: /(.|/)(gif|jpe?g|png)$/i, 19 20 add: function(e, data){ 21 if (data.files && data.files[0]) { 22 23 var reader = new FileReader(); 24 reader.onload = function(e) { 25 $('.preview').empty(); 26 $('.preview').append($('<img>').attr({// insert preview image 27 src: e.target.result, 28 id: "crop_img", 29 title: data.files[0].name 30 })); 31 $('#crop_img').cropper() // initialize cropper on preview image 32 }; 33 reader.readAsDataURL(data.files[0]); 34 }; 35 36 submitButton.on('click', function(){ 37 // crop のデータを取得 38 $('#crop_img').cropper('getCroppedCanvas').toBlob(function (blob){ 39 data.files[0] = new File([blob], data.files[0].name); 40 data.originalFiles[0] = data.files[0]; 41 data.submit(); 42 }) 43 }); 44 }, 45... 46 done: function(e, data) { 47 progressBar.text("Uploading done"); 48 49 // extract key and generate URL from response 50 var key = $(data.jqXHR.responseXML).find("Key").text(); 51 var url = '//' + form.data('host') + '/' + key; 52 53 // create hidden field 54 $("#post_remote_image_url").val(url); //hidden_field内のremote_image_urlの値にURLを入れる 55 var input = $("<input />", { type:'hidden', name: fileInput.attr('name'), value: url }); 56 form.append(input); 57 }, 58... 59 60 }); 61 }); 62}); 63

html

1... 2 <%= form_for @post, :url => { :controller => :posts, :action => :create } ,html: { class: "directUpload", data: { 'form-data' => (@s3_direct_post.fields), 'url' => @s3_direct_post.url, 'host' => URI.parse(@s3_direct_post.url).host } } do |f|%> 3 <div class="field" > 4 <%= f.label("アイテム画像(必須)") %> 5 <%= f.file_field :image_name %> 6 7 <%= f.hidden_field :remote_image_url %> 8 9 <div class="preview"><img id="crop_img" /></div> 10 <div class="clear_float"></div> 11 12 <%= f.hidden_field :user_id, :value => current_user.id %> 13 <div class="clear_float"></div> 14 15 <%= f.label("コメント") %> 16 <%= f.text_area :detail %> 17 18 <%= f.submit("投稿") %> 19 <% end %> 20...

ruby

1class PostsController < ApplicationController 2 ... 3 def new 4 @post = Post.new 5 end 6 7 def create 8 post = params.require(:post).permit( 9 :user_id, 10 :image_name, 11    :remote_image_url; 12 :detail 13 ) 14 @post = Post.new(post) 15 if @post.save 16 flash[:notice]="投稿しました" 17 redirect_to("/") 18 else 19 render("posts/new") 20 end 21 end 22... 23end

#試してみたこと
submitボタンがクリックされた際に、一度formのsubmitを中断
→画像のアップロード完了後に再開、という手段を試みました。
以下のようにコードを修正し、中断させることには成功しましたが、画像のアップロード完了後にformのsubmitをもう一度有効化することができていません。
何故有効化できないのでしょうか?ご意見をいただきたいです。

javascript

1$(function() { 2 ... 3 add: function(e, data){ 4 ... 5 submitButton.on('click', function(){ 6 //一度submitを中断させる 7 $('form').submit(function(){ 8 return false; 9 }); 10 // crop のデータを取得 11 $('#crop_img').cropper('getCroppedCanvas').toBlob(function (blob){ 12 data.files[0] = new File([blob], data.files[0].name); 13 data.originalFiles[0] = data.files[0]; 14 data.submit(); 15 }) 16 }); 17 }, 18 19 ... 20 21 done: function(e, data) { 22 submitButton.prop('disabled', false); 23 progressBar.text("Uploading done"); 24 25 // extract key and generate URL from response 26 var key = $(data.jqXHR.responseXML).find("Key").text(); 27 var url = '//' + form.data('host') + '/' + key; 28 29 // create hidden field 30 var input = $("<input />", { type:'hidden', name: fileInput.attr('name'), value: url }) 31 form.append(input); 32 //submitを再開させたいが、うまくいきません 33 $('form').submit(function(){ 34 return true; 35 }); 36 $('.directUpload').submit(); 37 console.log("upload done!!") //このログが表示されるため、doneコールバックはきちんと呼ばれています。 38 }, 39 40 fail: function(e, data) { 41 submitButton.prop('disabled', false); 42 43 progressBar. 44 css("background", "red"). 45 text("Failed"); 46 } 47 }); 48 }); 49}); 50

補足情報(FW/ツールのバージョンなど)

Ruby on Rails 5
jQuer-file-upload
Cropper.js

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

自己解決しました!
以下のコードで解決できました!!
参考:jQueryでフォームの送信を一旦止め、処理を挟んでから送信する方法

javascript

1done: function(e, data) { 2 submitButton.prop('disabled', false); 3 progressBar.text("Uploading done"); 4 5 // extract key and generate URL from response 6 var key = $(data.jqXHR.responseXML).find("Key").text(); 7 var url = '//' + form.data('host') + '/' + key; 8 9 // create hidden field 10 var input = $("<input />", { type:'hidden', name: fileInput.attr('name'), value: url }) 11 form.append(input); 12 13 $('form').off('submit'); //submitイベントを一旦リセット 14 $('.directUpload').submit(); 15 },

投稿2018/04/02 08:36

tacro

総合スコア23

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問