らくだ🐫にもできるRailsチュートリアル|13.4(と13.5)

※毎回書いたほうがいい気がするので書いておきます※
平文の部分をちょこちょこI18nで日本語化しているのですが
その部分に関しては特に記述していなくてもたまにコードが違ったりしています。
t(‘.hogehoge’)って部分です
どうぞお気になさらず。

13.4 マイクロポストの画像投稿

マイクロポストの基本的な操作は実装できたが
応用として画像付きのマイクロポストを投稿できるようにしていく。

開発環境用のβ版を実装

改善

本番環境用の完成版を実装

.gitignoreの編集

開発環境でアップロードされた画像がgitにpushされないように.gitignoreを編集しておく
(本文では最後の方に出てくるけど、途中でもコミットするのであれば設定しておく🐫)

※隠しファイルになっているので注意

画像アップロード機能を追加するために

アップロードするためのフォームと投稿された画像本体が必要!
[Upload image] ボタンと画像付きマイクロポストの見本はRoRT本文参照

13.4.1 基本的な画像アップロード

CarrierWaveという画像アップローダーを使って実装していく

まずはcarrierwave gemをGemfileに追加しましょう (リスト 13.58)15 。このとき、リスト 13.58ではmini_magick gemとfog gemsも含めている点に注目してください。これらのgemは画像をリサイズしたり (13.4.3)、本番環境で画像をアップロードする (13.4.4) ために使います。

そして

CarrierWaveを導入すると、Railsのジェネレーターで画像のアップローダーが生成できるようになる。
スゴイ!

Active Recordモデルの属性と関連付け

CarrierWaveでアップロードされた画像はActive Recordモデルの属性と関連付けされているべき!
→関連付けされる属性には画像のファイル名が格納される→ファイル名なので型はString型にしておく

picture属性を追加したマイクロポストのデータモデルはこちらの→RoRT本文
picture属性をMicropostモデルに追加する

CarrierWaveに画像と関連付けたモデルを伝えるためには、mount_uploaderというメソッドを使います。このメソッドは、引数に属性名のシンボルと生成されたアップローダーのクラス名を取ります。

Micropostモデルにアップローダーを追加

アップローダーのクラス名は自動生成されたpicture_uploader.rbで定義されている

viewにアップローダーを追加

Homeページにアップローダーを追加→_micropost_form.html.erbを編集

また、Webから更新できる許可リストにpicture属性を追加する

アップロードされた画像を表示できるようにする

一度画像がアップロードされれば、Micropostパーシャルのimage_tagヘルパーでその画像を描画できるようになります (リスト 13.62)。また、画像の無い (テキストのみの) マイクロポストでは画像を表示させないようにするために、picture?という論理値を返すメソッドを使っている点に注目してください。

「picture?」は画像用の属性名に応じて(今回はpicture)CarrierWaveが自動的に生成してくれます

image_tagヘルパーとは何ぞ

image_tagヘルパーは画像を表示するためのヘルパーメソッド

HTML imgタグを返します。画像へのフルパス、またはapp/assets/imagesディレクトリ内にあるファイルを引数として与えられます。



image_tag micropost.picture.url →生成されるHTML→ <img src=”画像のソース” alt=”ファイル名が入る”>
第2引数でオプションを指定することも可能(詳しくは上記リンクなどで勉強しましょう)

演習

  1. 画像付きのマイクロポストを投稿してみましょう。もしかして、大きすぎる画像が表示されてしまいましたか? (心配しないでください、次の13.4.3でこの問題を直します)。
  2. リスト 13.63に示すテンプレートを参考に、13.4で実装した画像アップローダーをテストしてください。テストの準備として、まずはサンプル画像をfixtureディレクトリに追加してください (コマンド例: cp app/assets/images/rails.png test/fixtures/)。リスト 13.63で追加したテストでは、Homeページにあるファイルアップロードと、投稿に成功した時に画像が表示されているかどうかをチェックしています。なお、テスト内にあるfixture_file_uploadというメソッドは、fixtureで定義されたファイルをアップロードする特別なメソッドです18 。ヒント: picture属性が有効かどうかを確かめるときは、11.3.3で紹介したassignsメソッドを使ってください。このメソッドを使うと、投稿に成功した後にcreateアクション内のマイクロポストにアクセスするようになります。

1.
動作確認のみにて省略
2.
※本文と若干違う部分があるけど手元のコード重視で

13.4.2 画像の検証

現状では画像サイズに対する制限がないので大きな画像も上げ放題!
また、フォーマットの指定もしていないので
大きなサイズや謎のファイルも上げ放題で危ない!
ので、バリデーションを設定する→サーバー用とクライアント用両方に追加する!!

有効な画像の種類を制限

生成されたアップローダーの中にコメントアウトされたコードがありますが、ここのコメントアウトを取り消すことで、画像のファイル名から有効な拡張子 (PNG/GIF/JPEGなど) を検証することができます

本文だとstore_dirメソッドのすぐ下にある感じだけど
🐫の環境では36行目~でした

画像サイズの制御

Micropostモデルに定義していく
画像サイズに関するバリデーションはpresenceやlengthなどと違ってRailsの既存オプションにはないので
手動で「picture_size」という独自のバリデーションを定義していく

バリデーションをViewに組み込む

上記の10行目acceptパラメーターは、送信できる(app/uploaders/picture_uploader.rbで許可した)ファイル形式をMIMEタイプで指定している

MIMEタイプとは何ぞ


大分類/詳細な形式
→image/png(imageファイル/png形式)、text/html(textファイル/html形式)とか

アラート用のjQueryのコード

ただしこのコードでは規定サイズ以上のファイルのアップロードは阻止できない
→メッセージを無視してアップロードを強行することも可能

本書はRailsチュートリアルなので、今回は「リスト 13.66のようなコードでは実装はまだ不完全である」という点だけ覚えておけば十分です。

今回Micropostモデルで設定したように、サーバー側でのバリデーションが重要!

演習

  1. 5MB以上の画像ファイルを送信しようとした場合、どうなりますか?
  2. 無効な拡張子のファイルを送信しようとした場合、どうなりますか?
    13.4.3
    • ファイル選択時Maximum file size is 5MB. Please choose a smaller file.のダイアログが出る
    • 気にせず投稿ボタンを押すとバリデーションエラーでメッセージが出る
    • そもそも投稿ファイルは指定の拡張子から選ぶようになってるので無効な拡張子を選ぶことはなかなかない
    • 「すべてのファイル」から選んで送信ボタンを押すとバリデーションエラーでメッセージが出る

13.4.3 画像のリサイズ

ファイルサイズに対するバリデーションを設定したけど画像サイズ(縦横の長さ)に対する制限がないので
(縦横のサイズ的に)大きすぎる画像がアップロードされるとレイアウトが崩れてイヤンな気持ちになる
→適切なサイズにリサイズする

他の解決策としてCSSで表示サイズを調整する方法もありますが、これだとファイルサイズが変わりません。結果として、ファイルサイズの大きな画像によって、読み込み時間が長くなるといった問題が発生します。

画像をリサイズするプログラムを導入

ImageMagickというプログラムを使うので、これを開発環境にインストールする
※環境によって手順が異なる!(ググろう)※Herokuではもともと導入されている
クラウドIDEでは下記

次に、MiniMagickというImageMagickとRubyを繋ぐgemを使って、画像をリサイズしてみましょう。

今回は最大幅を400pxに定める→縦横どちらかが400pxを超えていた場合に適切にリサイズ

演習

  1. 解像度の高い画像をアップロードし、リサイズされているかどうか確認してみましょう。画像が長方形だった場合、リサイズはうまく行われているでしょうか?
  2. 既にリスト 13.63のテストを追加していた場合、この時点でテストスイートを走らせると紛らわしいエラーメッセージが表示されることがあります。このエラーを取り除いてみましょう。ヒント: リスト 13.68にある設定ファイルを修正し、テスト時はCarrierWaveに画像のリサイズをさせないようにしてみましょう。
  1. 縦横比を保ったままリサイズされる
  2. エラーにならなかったのでわかりません🤔

13.4.4 本番環境での画像アップロード

13.4.3で実装した画像アップローダーは、開発環境で動かす分には問題ないのですが、本番環境には適していません。これはリスト 13.67のstorage :fileという行によって、ローカルのファイルシステムに画像を保存するようになっているからです

なので、本番環境でも使えるようにする
→本番環境ではクラウドストレージサービスに画像を保存→13.4.1で導入したfog gemを使うと簡単!

環境のセッティング

RoRT本文に則ってAWSで色々する
/sample_app/config/initializers/carrier_wave.rbを作って(本来はファイルがあるものっぽい?)S3用に定義

環境変数を設定

いつものようにテストしてaddしてcommitしてpushしてぎとはぶでプルリクしてマージして戻ってきてpullる
そしてHerokuへデプロイる

演習

  1. 本番環境で解像度の高い画像をアップロードし、適切にリサイズされているか確認してみましょう。長方形の画像であっても、適切にリサイズされていますか?
  1. される!

13.5 最後に

まとめにつき割愛

まとめとか感想

本文より寄り道な部分に時間がかかった気がしますがコミュで助けてもらいつつ頑張りました!
さぁ!もう一息頑張ろうねええええ!!!!!

らくだ🐫にもできるRailsチュートリアルとは

「ド」が付く素人のらくだ🐫が勉強するRailsチュートリアルの学習記録です。
自分用に記録していますが、お役に立つことがあれば幸いです。

調べたとはいえらくだ🐫なりの解釈や説明が含まれます。間違っている部分もあるかと思います。そんな所は教えて頂けますと幸いなのですが、このブログにはコメント機能がありません💧お手数おかけしますがTwitterなどでご連絡いただければ幸いです