初学者の備忘録
初学者の備忘録です。今回は画像投稿機能- ActiveStorage - 編
ActiveStorage
今回は画像投稿機能としてActiveStorageを使用した方法になります。
ActiveStorageとはRailsで画像の投稿や表示を行うためのものです。画像は通常のカラムとして保存できないため、特別な保存方法が必要になり、それを行うのがActiveStorageです。
導入
ActiveStorageを使うためにActiveStorageをインストールします。
インストールが終わるとdb/migrateディレクトリ内にActiveStorageのマイグレーションファイルが追加されます。マイグレーションファイルをUP状態にするためのコマンドも行っておきます。
$ rails active_storage:install
$ rails db:migrate
導入は以上です。
【1】 宣言
ActiveStorageを使って画像を表示する際には、どのモデルに対して画像を使うのかを宣言する必要があります。
has_one_attached :image
モデルで宣言することによって画像を扱うためのimageカラムが追記されたかのように扱うことができます。
【2】no_image
画像が存在しない場合に別の画像を表示させるためのメソッドを定義していきます。なくても大丈夫です。好みの問題です。
:
:
# No_imageが存在するかどうか判断するメソッド
def get_place_image
# 存在しなかった場合no_image.pngを使用
(image.attached?) ? image : 'no_image.png'
end
:
:
'no_image.png'はご自身の好きな画像をご使用ください。
【3】 view
準備は終了したので次は投稿フォームに画像投稿フォームを作成していきます。
今回は私が実際に実装したものを載せますが、ご自身で自由にレイアウトを整えてください。
:
:
<!--画像フォーム-->
<div class="row">
<div class="col-12 w-100">
<!--画像が存在するかどうか判断-->
<% if place.image.attached? %>
<%= image_tag place.image, style: "width: 50;", id: 'imagePreview', class: "img-fluid mb-3" %>
<% else %><!--存在しなかった場合-->
<%= image_tag "place_no_image.png", style: "width: 50;", id: 'imagePreview', class: "img-fluid mb-3" %>
<% end %>
</div>
</div>
<!--画像フォーム-->
<%= f.file_field :image, id: "imageField" %>
:
:
本当はもっとスッキリまとまったコードが記述できるのですが、発展でJavaScriptを使用したプレビュー機能を作成したのであえて冗長なコードにしています。まとめるとJavaScriptが機能しなくなりますので。
JavaScriptで重要なのはid: 'imagePreview'
の部分なのでimagePreview
はご自身がわかりやすいように変更してください。
プレビュー機能はいらない
JavaScriptを使用せずプレビュー機能はいらない。画像投稿だけできればいいという方向けに1行の画像投稿コードは下記のようになります。
<%= image_tag place.get_place_image, style: "width: 50;", class: "img-fluid mb-3" %>
これだけで画像投稿フォームが機能します。
【4】 プレビュー機能(発展機能)
JavaScriptはまだまだ学習中で理解できていないので説明はできませんし、間違ったコメントがあるかもしれませんが機能としてはできているので投稿しておきます。
:
:
// viewを読み込んだ後に実行(イベントを使用する場合は使用する場合が多い)
$(document).on('turbolinks:load', function() {
// 画像アップロードフィールドの変更イベントが発生したときの処理
$('#imageField').on('change', (e) => {
// 選択されたファイルを取得(ver=変数宣言)
// 画像選択したら発火(0=1枚)
var file = e.target.files[0];
// FileReaderオブジェクトを作成
// FileReader():JavaScriptのプログラム new:classをオブジェクトに作成
var reader = new FileReader();
// 読み込み完了時に処理(file=>f)
reader.onload = (f) => {
// プレビュー画像のsrc属性を選択した画像ファイルのDataURLに設定=>viewへ
$('#imagePreview').attr('src', f.target.result)
}
// 画像ファイルをDataURL形式で読み込む
reader.readAsDataURL(file);
});
});
:
:
私の場合複数の箇所でプレビュー機能を使用したのでapplication.jsに記述しましたが、特定のページや機能だけで使用する場合は別のjsファイルを使用しても大丈夫です。
機能しているかどうかわからない場合は検証ツールでコンソールでエラーが出ていないか確認。エラーが出ていた場合console.log();でイベントが機能しているかどうか確認しましょう。
最後に
画像投稿は何度か苦戦したところなので忘れた時などにためになればいいなと思っています。JavaScriptも今回は1枚の画像投稿だけですが、複数画像投稿できる機能になると別のコードを加えないといけないのでまだまだ勉強しないとわかりません。
ではこれで終わりたいと思います。お疲れ様でした。