【rails】画像のアップロード(ActiveStorage)

※本サイトで紹介している商品・サービス等の外部リンクには、アフィリエイト広告が含まれる場合があります。

ActiveStorage

画像のアップロードを扱うために、railsが用意したデフォルト機能のこと

ターミナルでインストールする

rails active_storage:install
# => (前略)
# Copied migration 20240908215240_create_active_storage_tables.active_storage.rb from active_storage

新しいマイグレーションファイルが出来上がった

2つのテーブルが作られて、画像のデータや保存先について設定がされている

ターミナルでマイグレーションファイルを読み込む

rails db:migrate


アバターの設定

「アバター」というデータをアップロードできるように設定する

app/models/profile.rbを開く

class Profile < ApplicationRecord
 # 中略
  has_one_attached :avatar
  • プロフィールにアバターの概念を追加する(カラムを増やす感じ、実際には増えない)
  • プロフィールにはアバターという画像をアップロードすることができる


アバターの保存を許可しておく

app/controllers/profiles_controller.rbを開く

:avatarを追加する

  private
  def profile_params
    params.require(:profile).permit(
      :nickname,
      :introduction,
      :gender,
      :birthday,
      :subscribed,
      :avatar
    )
  end

Strong Parameterでセキュリティを担保する

アップロードのボタンを作る

app/views/profiles/adit.html.hamlを開く

ファイルをアップロードできるようにfile_fieldを追加する

    %div
      = f.label :avatar, 'アバター'
    %div
      = f.file_field :avatar


実際にアップロードしてみると、なにか保存できている

保存できたので表示してみる

アバターを表示する

profiles/show.html.hamlを開く

      - if current_user.profile&.avatar&.attached?
        = image_tag current_user.profile.avatar
      - else
        = image_tag 'default-avatar.png'

&. ぼっち演算子

プロフィールの有無、アバターの有無でエラーが起きないようにする

 - if current_user.profile&.avatar&.attached?
  1. current_user.profilenil
    → current_user.profile&.以降は実行されない
  2. current_user.profileは存在するけど、avatarnil
    → avatar&.以降は実行されない
  3. current_user.profileは存在するし、avatarも存在する
    → attached?が実行され、アップロードされた画像を表示する
【rails】プロフィールを表示する

else(アップロードされた画像がない場合)

'default-avatar.png'を表示する


何回も使うコードはメソッドにする

アバターの表示箇所は複数あるので、何回も同じコードを書かないといけない

avatar_imageを定義する

  • アップロードされている場合は、アップロードされた画像を表示
  • アップロードされていない場合は、デフォルト画像を表示

app/models/user.rbを開く

  def avatar_image
    if profile&.avatar&.attached?
      profile.avatar
    else
      'default-avatar.png'
    end
  end

メソッドにまとめると、各viewがすっきりする

 # commons/_article.html.haml
= image_tag article.user.avatar_image

 # layouts/application.html.haml header部分
= image_tag current_user.avatar_image, class: 'header_avater dropbtn'

 # articles/show.html.haml
= image_tag @article.user.avatar_image

 # profiles/show.html.haml
= image_tag current_user.avatar_image

#DAY24