0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【React × Rails API】Active Storageで画像URLを取得し、フロントエンドに表示する方法

0
Posted at

はじめに

この記事は、プログラミング初学者が他の記事を参考にしたり、実際に実装してみたりして、アウトプットの一環としてまとめたものです。内容に不備などあればご指摘いただますと幸いです。

この記事では、以下を解説しています。

  • Active Storage で保存した画像の URL を取得する方法
  • variant(リサイズ)した画像をフロントエンドで表示する方法
  • API として画像の URL を返却する方法

ActiveStorageの準備

ActiveStorageが未導入の場合は以下を実行します。

$ rails active_storage:install
$ rails db:migrate

画像処理をするため、image_processingを入れます。
Gemfile に下記を記述し、bundle install します。

gem 'image_processing', '~> 1.2'

Rails7以降にvariantでimage_magickを使う場合は
デフォルトの設定がvipsになっているため
config/application.rbに下記を記述します。

config/application.rb
config.active_storage.variant_processor = :mini_magick

モデルの定義

下記を記述することで、ActiveStorage の URL を取得できます。

app/models/tweet.rb
class Tweet < ApplicationRecord
  belongs_to :user
  has_one_attached :image

  # 画像のURL変換メソッド(リサイズあり)
  def image_url(width, height)
    resize_image = image.variant(resize_to_fill: [width, height]).processed
    Rails.application.routes.url_helpers.rails_representation_url(resize_image, only_path: false)
  end

  # 画像のURL変換メソッド(リサイズなし)
  def image_url
    Rails.application.routes.url_helpers.rails_blob_url(image, only_path: false)
  end
end

ポイント

has_one_attached :image

  • 1レコードに1つの画像を紐づけられる

variant

  • 画像をリサイズ・加工するActiveStorageの機能
  • resize_to_fill は指定サイズで中央トリミングされる

processed

  • variant の後ろに、processed メソッドをつけると既に同じ加工を施したデータがないかを確認し、存在する場合はそれを呼び出します

Rails.application.routes.url_helpers

  • Rails の ルーティングヘルパーを直接呼び出すためのオブジェクト
  • URLヘルパーをビューやコントローラ以外の場所で使う場合に必要

rails_representation_url

  • variantを含む画像のURLを生成

rails_blob_url

  • 画像の絶対URLを生成

only_path: false

  • URL を 絶対URL にするかどうか
  • true → /rails/... のような パスだけ
  • false(もしくは省略) → http://localhost:3000/rails/... のような 絶対URL

補足

Railsは 用途別にURLヘルパ を用意しています。

  • blob(Active Storageを使用し、リサイズなし) → rails_blob_url
  • variant(Active Storageを使用し、リサイズあり) → rails_representation_url
  • view内だけ → image_tag / url_for

ルーティング設定

URL生成には ホスト情報 が必要です。(only_path: false の場合、必須)
下記を記述します。

config/environments/development.rb
Rails.application.routes.default_url_options[:host] = 'http://localhost:3000'

本番環境でも同様に設定します。

コントローラで画像URLを返す

APIとしてTweetを返す例です。

app/controllers/api/v1/tweets_controller.rb
module Api
  module V1
    class TweetsController < ApplicationController
      def index
        tweets = Tweet.includes(image_attachments: :blob)

        render json: tweets.map { |tweet|
          {
            id: tweet.id,
            content: tweet.content,
            image: tweet.image_url(500, 270)
          }
        }
      end
    end
  end
end

ポイント

Tweet.includes(image_attachments: :blob)

  • tweetsテーブルから全てのデータを取得します
  • includes で N+1クエリを防ぎます

フロントエンドでの表示例

{tweet.image && <img src={tweet.image} />}

レスポンスで返却された画像URLを src 属性に設定し、
画像が存在する場合のみ表示されるようにしています。

おわりに

最後まで読んでいただきありがとうございました。

参考にしたサイト

0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?