LoginSignup
1
0

More than 1 year has passed since last update.

【Ruby on Rails】Active Storageを使った画像アップロード

Last updated at Posted at 2023-02-05

はじめに

Rails勉強中のエンジニア初心者が他の記事を参考にしたり、実際に実装してみたりして、アウトプットの一環としてまとめたものです。
間違っていることもあると思われるので、その際は指摘いただけると幸いです。

Railsガイド

Railsでの画像アップロード

代表的な方法として下記2つのパターンがあるが、1について記載する。
Rails5.1まではcarrierwaveというGemのインストールが一般的であったが、
Rails5.2以降はActive storageという便利機能が追加されたため、新たなGemのインストールは不要となった。

  1. Active Storageimage_processingを使用する
  2. carrierwavemini_magicを使用する

Active Storageとは

  • Active Storageは、Rails5.2で追加されたファイルアップロードを行うための機能で、フォームでの画像の投稿機能などが簡単に実装できる
  • Amazon S3Google Cloud StorageMicrosoft Azure Storageなどのクラウドストレージサービスに対しても、ファイルのアップロードを簡単に行うことができる
  • クラウドストレージの他に、ローカルディスクにファイルを保存することもでき、開発環境ではローカルストレージにファイルを保存して、本番環境ではクラウドストレージにファイルを保存するなど、環境毎に保存先を切り替えることもできる
  • PaperclipCarrierwaveDragonflyなどのGemの代わりになると言われている

Active Storageをインストールする

rails active_storage:installを実行するとActive Storageを使用するために必要となるテーブルを作成するためのマイグレーションファイルが自動で作成される(active_storage_boldsactive_storage_attachementsactive_storage_variant_records

実行コマンド

rails active_storage:install
rails db:migrate

Active Storageの実装

モデルの編集

Active Storageを使って画像などのデータを既存のテーブルと紐づけるために、

モデルファイルにhas_one_attached :カラム名を追加する(has_one_attachedActive Storageで使う指定方法)。

シンボルで指定するカラム名でそのデータを扱うため分かりやすい名称にする。例えば、画像なら:image、動画なら:movie、アバターなら:avatarなど。

モデルファイルへの記載方法

```ruby
# 1ファイルの場合
has_one_attached :image

# 複数ファイルの場合
has_many_attached :images
```

実際の記述例

# Roomモデルにアイコンとして画像を1つ紐づける場合
class Room < ApplicationRecord
  has_one_attached :image    
end

コントローラの編集

モデルファイルで関連付けたActive Storageのデータをパラメータで受け取ることができるように、ストロングパラメータに対象のカラム名を追加する。

  • 実際の記述例

    class RoomsController < ApplicationController
      def create
        @room = Room.new(room_params.merge(user_id: current_user.id))
        if @room.save
          flash[:notice] = "ルームを登録しました"
          redirect_to :rooms
        end
      end
    
      private
    
      def room_params
        params.require(:room).permit(:room_name, :room_introduction, :usage_fee, :address, :image)
      end
    end
    

ビューの編集

  • ビューへの記載方法

    # 画像を登録するフォーム
    <%= form.file_field :image %>
    
    # 登録されている画像を表示する
    <%= image_tag @room.image %>
    
  • 実際の記述例

    # 登録フォーム
    
    <%= form_with model: room do |f| %>
    
      <%= f.label :image, 'ルーム画像' %>
      <%= f.file_field :image, required: true %>
    
    	<%= f.submit '登録', class: 'submit-button' %>
    <% end %>
    
    # 画像の表示
    # 画像が登録されていないとエラーになるため、if room.image.attached?で画像が登録されている場合のみ表示する
    <% @rooms.each do |room| %>
      <%= link_to(new_reservation_path(id: room.id)) do%>
        <p><%= image_tag(room.image.variant(resize: 399)) if room.image.attached? %></p>
      <% end %>
    <% end %>
    

画像のサイズ変換

アップロードした画像をビューで表示するときに画像サイズを変換することができる。一覧ページでは画像サイズを100×100で表示し、詳細ページでは300×300で表示する場合などは、Active Storagevariant(バリアンと)という機能を使用する。

variantを使用すると、アップロードした画像を基にして簡単に画像のサイズを変更することが作成できる。

variantを使用するためには、ImageProcessingというGemをインストールする必要がある。

# Use Active Storage variant
gem 'image_processing', '~> 1.2'

ImageProcessingは内部の画像プロセッサとしてMiniMagickというGemを使用しており、MiniMagickImageMagickというソフトウェアのGem版であるため、ImageMagickがインストールされていないと動かない。

ImageMagick >> MiniMagick >> ImageProcessing >> variantという流れ

そのため、ImageProcessingを使うためには、ImageMagickをインストールする必要がある。

この手順は本番環境でも行う必要があるため注意が必要。

# Macの場合
$ brew install imagemagick

# Ubuntuの場合
$ sudo apt-get install imagemagick

# バージョン確認
$ convert --version
  • variantによる画像のリサイズ

    <%= image_tag room.image.variant(resize: 399) %>
    
  • オプション一覧

    オプション 説明
    gravity 画像変換の始点。convert -list gravityで指定値一覧を表示(デフォルトはNone)。
    resize 画像のサイズ。詳しくは Image Geometry - ImageMagick 参照。
    crop 始点からの切り抜きサイズ。
    precessed 既に変換済みであれば変換しない(キャッシュを表示)。

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0