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

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

新規登録して質問してみよう
ただいま回答率
85.50%
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

解決済

2回答

1671閲覧

[Rails5][Javascript]Javascript上の変数の値をRails側に渡したい

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 01:41

編集2018/04/02 03:44

前提・実現したいこと

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内で、railsのimage_nameに渡す変数を指定したいのですが、どのように処理すれば可能でしょうか?
アドバイスをよろしくお願いいたします。

該当のソースコード

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 //このあたりで、urlをimage_nameの値として渡す処理を加えたい 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 <div class="preview"><img id="crop_img" /></div> 8 <div class="clear_float"></div> 9 10 <%= f.hidden_field :designer_id, :value => current_user.id %> 11 <div class="clear_float"></div> 12 13 <%= f.label("コメント") %> 14 <%= f.text_area :detail %> 15 16 <%= f.submit("投稿") %> 17 <% end %> 18...

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 :detail 12 ) 13 @post = Post.new(post) 14 if @post.save 15 flash[:notice]="投稿しました" 16 redirect_to("/") 17 else 18 render("posts/new") 19 end 20 end 21... 22end

#試してみたこと
Ruby側でimage_nameを該当のURLに変更できるように、以下のことを試みました。

Ruby

1#Postモデル 2class Post < ApplicationRecord 3 ... 4 attr_accessor :remote_image_url #JavascriptからURLを受け取る仮想属性を宣言 5 validates :image_name, {presence: true} 6 validates :designer_id, {presence: true} 7end 8

html

1<%= 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|%> 2 <div class="field" > 3 <%= f.label("アイテム画像(必須)") %> 4 <%= f.file_field :image_name %> 5 <!--hidden fieldを置いて、アップロードした画像のURLを入れるようにする--> 6 <%= f.hidden_field :remote_image_url %> 7 8 ... 9 <% end %>

javascript

1$(function() { 2 ... 3 ... 4 done: function(e, data) { 5 ... 6 // extract key and generate URL from response 7 var key = $(data.jqXHR.responseXML).find("Key").text(); 8 var url = '//' + form.data('host') + '/' + key; 9 10 // create hidden field 11 var input = $("<input />", { type:'hidden', name: fileInput.attr('name'), value: url }); 12 $("#post_remote_image_url").val(url); //hidden_field内のremote_image_urlの値にURLを入れる 13 form.append(input); 14 }, 15... 16... 17});

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 :designer_id, 10 :image_name, 11 :remote_image_url, 12 :detail 13 ) 14 post[:image_name]= post[:remote_image_url] //image_nameの値にURLを入れる 15 post[:remote_image_url] = "" //remote_image_urlを空白に 16 @post = Post.new(post) 17 if @post.save 18 ... 19 end 20 end 21... 22end

しかし以上の方法では、image_nameが空白になってしまうようでバリデーションに引っかかります。
remote_image_urlをうまく渡せていないのが原因だと思うのですが、何かご指摘あればよろしくお願いいたします。

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

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

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

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

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

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

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

guest

回答2

0

(ここが原因というわけじゃないけれど)
変数名を見てやりたいことを慮ると、originalFiles[0]files[0]の入れ替え処理部が逆じゃね?

JavaScript

1 submitButton.on('click', function(){ 2 // crop のデータを取得 3 $('#crop_img').cropper('getCroppedCanvas').toBlob(function (blob){ 4 data.originalFiles[0] = data.files[0];//元画像をこっちに移しておいて 5 data.files[0] = new File([blob], data.files[0].name);//画像データを入れ替える 6 //data.originalFiles[0] = data.files[0]; 7 data.submit(); 8 }) 9 }); 10

投稿2018/04/02 02:05

defghi1977

総合スコア4756

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

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

tacro

2018/04/02 02:13

ご回答ありがとうございます。 ご指摘いただいた通りコードを修正しても動作に変わりがなかったので問題ないとは思うのですが、そもそもoriginalFiles[0]の存在意義がよくわからなくなってしまいました…
defghi1977

2018/04/02 02:18

Ruby側がリクエストのどの部分を見てファイル名としているのかが判らんので, JavaScript側でどうこう言っても始まらんのですよ. 逆に言えば, そこさえ分かれば問題は直ぐに解決すると思います. ※が、私はRubyを知らんので、アドバイスができんとですよ
defghi1977

2018/04/02 02:23

さっきの回答は ・ファイル名->オリジナルの画像データから取得 ・トリミング済み画像データ->toBlobから取得した画像データから取得 とするなら、加工前後の二つの画像をサーバーに渡せばよい. でも、コードを見る限り、オリジナルの画像を加工済みの画像で上書きしているので、少なくともこのままではうまく行かない…との判断からのものです. あとは、正しく ・オリジナル画像が送信されること ・ruby側でオリジナル画像を受信できていること を確認する必要があります.
tacro

2018/04/02 03:31

なるほど、ありがとうございます! ファイル名の部分をRuby側で調節できるよう修正してみます!
tacro

2018/04/02 06:22

デバッグを繰り返してみたところ、原因が他のjs部分にありそうです… 新しく質問し直しましたので、もしよければご覧いただけると幸いです。 [JavaScript]jQueryのコールバックが呼ばれない https://teratail.com/questions/120008?modal=q-comp
guest

0

自己解決

一通りデバッグしてみたところ、原因が別にありそうなので、新しく質問し直しました。
[JavaScript]jQueryのコールバックが呼ばれない

投稿2018/04/02 06:21

tacro

総合スコア23

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問