🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ruby on Rails 5

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

Ruby

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

Q&A

解決済

1回答

1713閲覧

Active Storage ~storage/以下にアップロードしたテキストファイル がgetしたい~

退会済みユーザー

退会済みユーザー

総合スコア0

Ruby on Rails 5

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

Ruby

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

0グッド

0クリップ

投稿2019/11/14 09:18

編集2019/11/15 09:55

###1 開発環境
ruby 2.4.1p111
Rails 5.2.3
mysql Ver 14.14

###2 背景
Active Storageを使用して、テキストファイルを、storage/以下にアップロードし、そのファイルをコントローラーから呼び出して、別のプログラムに組み込んで計算結果を取得する機能を実装している。
参照サイト:【Rails 5.2】 Active Storageの使い方

###3 やったこと
参照サイトの内容をほぼ真似させていただいて、ファイルのアップロードについては完了している。
しかし、アップロードしたファイルをstorage/以下から取得してくることができておらず、参照サイトの方法から私が予測できたことが、予測とは異なっていたため、困っている。

####3-1 参照サイトを丸パクリしたコード
Controller

Rails

1class ContextsController < ApplicationController 2 def new 3 @context = Context.new 4 end 5 6 def create 7 @context = Context.create params.require(:context).permit(:file_name) 8 redirect_to @context 9 end 10 11 def show 12 @context = Context.find(params[:id]) 13 end 14end

View

Rails

1<% if @context.file_name.attached? %> 2 <%= image_tag @context.file_name %> 3<% end %>

####3-1-1 参照サイトを丸パクリした結果
・画像ファイルをアップデートすると、画像が表示される。

予想したこと
・image_tagの引数となっている@context.file_nameは絶対パスに等しい情報を持っているのではないか?

###3-2 自分で書き直し、試したこと。およびその時のコード
Controllerに変更点はない。
View

Rails

1<% if @context.file_name.attached? %> 2 <%= `cat #{@context.file_name}` %> 3<% end %>

なぜこのコードを書いたか?
→**「3-1-1」**で画像ファイルがViewの画面で問題なく表示されたことと、image_tagの引数に、今まで絶対パスを記述してきた経験を合わせて、@context.file_nameには絶対パスに近い情報が入っていると予想した。
よって、テキストファイルであれば、catコマンドの引数として与えれば、中身が表示できるはず!と考えたが、できなかった。
なぜできないのかを確かめるために、@context.file_nameを出力したところ、

terminal

1#<ActiveStorage::Attached::One:0x007faaa59085b0>

と出力され、絶対パスが入っているわけではなかった。

###3-2-1 自分で書き直し、試したこと。およびその時のコードその2
Controller側の中でcatコマンドをしてみた。
Controller

Rails

1class ContextsController < ApplicationController 2 def new 3 @context = Context.new 4 end 5 6 def create 7 @context = Context.create params.require(:context).permit(:file_name) 8 # redirect_to :action => 'kegg_result' 9 redirect_to @context 10 end 11 12 def show 13 @context = Context.find(params[:id]) 14 logger.info("--------------") 15 logger.info(@context.file_name) 16 if @context.file_name.present? 17 @content = `cat #{@context.file_name}` 18 end 19 end 20end

View

Rails

1<%= @content %>

結果
→localhostを待機しています。と左下に表示が出ていて、ブラウザはずっと読み込み中。おそらく、上手く入っていないのであろう。

###最後に
Railsガイドこちらを参照してみたが、ファイルのstorage/からテキストファイルをgetする方法がいまいちわからないです。
私としては、image_tagで画像が表示できるのに、ファイルは取得してこれないことに、頭の中が「?????」となっております。
識者の方、教えていただけると嬉しいです。よろしくお願いします。

###asm様のご提示いただいた内容の結果

Ruby

1 def show 2 @context = Context.find(params[:id]) 3 if @context.file_name.present? 4 @context_file = @context.file_name.download 5 @stdin = `cat #{@context_file}` 6 end 7 end

すみません、提出するファイルによっては、catでうまく出力ができないみたいなので少し時間かかります。
提示していただいた内容についてはこれで大丈夫であると思われます。
今日中に完成させます。

case1
permission deniedがログのエラーとして発生しているようです。
https://qiita.com/takuyanin/items/18590600d077df707923
少し勉強します。
→これは使用したテキストファイルに制限がかかっていることが原因でした。

case2
自分で作成したテキストファイルをアップロードしてみました。
作成したファイルに書いた文言

text.txt

1こんにちは 2初めまして 3おはよう 4こんばんは 5お疲れ様です 6どうにか 7プログラムが 8動いたみたいだ 9一安心だね

catコマンドはなんだか問題ありそうだったので、python3で簡単なプログラムを作成して、これで動かしてみました。
結果→incompatible character encodings: UTF-8 and ASCII-8BIT
エラー出てますね。これは別問題なのでどうしましょうと言った感じです。
でも、ターミナルでは出力が出ていました。しかし、Viewファイルには出力出ていないですね。。

こんにちは 初めまして おはよう こんばんは お疲れ様です どうにか プログラムが 動いたみたいだ 一安心だね

case3
別の(結果をお見せすることができない)テキストファイルをinputすると、ターミナルにて、その内容がログに出力されていました。
ここで使用したファイルは卒論にて使用するためのファイルなのでお見せできません。申し訳ないです。
しかし、とりあえずファイルをpython3で作成したプログラムに渡すことができたので、1つの区切りとすることができました。

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

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

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

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

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

guest

回答1

0

ベストアンサー

image_tagなどのviewヘルパーはurlを渡されるところにurl以外を渡されるとurl_forを用いてurlへの変換を自動的に行います。
image_tag

The source can be a full path, a file, or an Active Storage attachment.

と、attachmentが渡せるようになっていました。

link_toform_with等はurlに文字列以外を渡されるとurl_forに渡してurlを取得します。


Active Storage の概要にありますが、url_forにBlobを渡すとパーマネントurlを生成するので画像が表示できます。

同解説にありますが、

ruby

1@content = @context.file_name.download 2# もしくは 3@content = @context.file_name.open do |f| 4 `cat #{f.path}` 5end

になるかと思います。

投稿2019/11/15 07:41

編集2019/11/15 09:39
asm

総合スコア15149

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

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

退会済みユーザー

退会済みユーザー

2019/11/15 08:45

ご回答ありがとうございます。 >image_tagなどのviewヘルパーはurlを渡されるところにurl以外を渡されるとurl_forを用いてurlへの変換を自動的に行います。 え!!!!と声がでしまいました。全く知らなかったですし、「rails image_tag」でググっても見たのですが、全く関係ない基本的な情報ばかりでした。 ご提示いただいた内容についてはすぐに試させていただきます。
退会済みユーザー

退会済みユーザー

2019/11/15 08:55

ご回答をいただいたばかりで大変恐縮なのですが、追加質問をしてもよろしいでしょうか? 質問内容 >Active Storage の概要にありますが、url_forにBlobを渡すとパーマネントurlを生成するので画像が表示できます。 →実際にリンクに飛んで確認しました。実は何度も何度もこのサイトを見ていたのですが、サイトに書かれている言葉と自分が実装したい内容を言語化したものが一致していないことを再確認することになりました。 サイトから引用 >アップロードしたblobに対して処理を行う(別フォーマットへの変換など)必要が生じることがあります。ActiveStorage::Blob#downloadを用いてblobのバイナリデータをメモリに読み込めます。 >場合によっては、blobをディスク上のファイルとしてダウンロードし、外部プログラム(ウイルススキャナーやメディアコンバーターなど)で処理できるようにしたいことがあります。ActiveStorage::Blob#openでblobをディスク上のtempfileにダウンロードできます。 これらの言葉が、自分の実装したい内容を自分で言語化したものと一致しなかったのが原因だと思われます。 このような状態から脱却し、プログラマーとして迅速な実装を可能にするためにはこれらの言葉を理解するのが最も早いでしょうか? 例えば、「blobのバイナリデータをメモリに読み込む」であったり、「blobをディスク上のファイルとしてダウンロードし」であったりの言葉はITに携わるのであればデフォルトとして知っておくべき知識なのでしょうか? アドバイスお願いします。
退会済みユーザー

退会済みユーザー

2019/11/15 09:02

ご提示いただいたものを導入した結果については、質問内容の方に追記いたします。 無事解決したと考えられます。 また、追加質問についてご好意でお答えいただけることを願いまして、ベストアンサーはまだ決定しないつもりです。ぜひお答えいただけると幸いです。 なお、ベストアンサーは追加質問に対する返答の有無に関わらずasm様が確定しております。
asm

2019/11/15 09:27

> url_for ちゃんと調べたら少し違ってたので訂正します。 (url_forによる変換が行われるhelperがあるのは本当ですが、image_tagはちょっと違うっぽい) > 例えば、「blobのバイナリデータをメモリに読み込む」であったり、「blobをディスク上のファイルとしてダウンロードし」であったりの言葉はITに携わるのであればデフォルトとして知っておくべき知識なのでしょうか? うーん、正直イマイチな解説に私も感じています。 ActiveStorageがS3等の外部ストレージを抽象的に扱うためのものであって ローカルのファイルを扱うだけのものじゃないので若干特殊な用語(blob)についての知識が必要になりますが blob = 何らかのストレージに格納されたバイナリデータ、ファイルを抽象化した感じのもの という知識があれば読解できるかなーと思います。
退会済みユーザー

退会済みユーザー

2019/11/15 09:50

>> url_for >>ちゃんと調べたら少し違ってたので訂正します。 ありがとうございます。こちら確認します。 >>うーん、正直イマイチな解説に私も感じています。 ActiveStorageがS3等の外部ストレージを抽象的に扱うためのものであって ローカルのファイルを扱うだけのものじゃないので若干特殊な用語(blob)についての知識が必要になりますが blob = 何らかのストレージに格納されたバイナリデータ、ファイルを抽象化した感じのもの という知識があれば読解できるかなーと思います。 やはり難解なものなのですね。しかし、blobのイメージがつかめていればよかったのですね。イメージを手に入れるためには経験が必要そうですね(汗) このようなミスをこれからも犯していくことになるのでしょうね。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問