LoginSignup
4
7

More than 3 years have passed since last update.

【Rails】Active Storage(画像保存の設定)

Last updated at Posted at 2020-12-13

使用するツール

Active Storage(gem) ※railsに最初から入っている。
MiniMagick(gem)
ImageProcessing(gem)
ImageMagick

実装手順

ImageMagickをインストール

% brew install imagemagick

Gemをインストール

gem 'mini_magick'
gem 'image_processing', '~> 1.2'

Active Storageをインストール

% rails active_storage:install
% rails db:migrate

rails active_storage:installコマンドを実行すると、Active Storageに関連したマイグレーションが作成されます。続けてマイグレートしましょう。

画像の保存

Active StorageのテーブルとMessagesテーブルのアソシエーションを定義
messages_controller.rbにて、imageカラムの保存を許可

has_one_attachedメソッド

各レコードとファイルを1対1の関係で紐づけるメソッド

class モデル < ApplicationRecord
  has_one_attached :ファイル名
end

:ファイル名には、添付するファイルがわかる名前をつけましょう。
この記述により、モデル.ファイル名で、添付されたファイルにアクセスできるようになります。また、このファイル名は、そのモデルが紐づいたフォームから送られるパラメーターのキーにもなります。

画像の保存を許可するストロングパラメーター

 def message_params
    params.require(:message).permit(:content, :image).merge(user_id: current_user.id)
  end

保存した画像を表示

image_tagメソッド

# ファイルをモデルから指定する場合
<%= image_tag モデル名.has_one_attachedで設定したファイル名 %>
<%= image_tag user.avatar %>

# app/assets/ディレクトリ下の画像ファイルパスでも指定できる
<%= image_tag 画像ファイルのパス %>
<%= image_tag "avatar.png" %>

attached?メソッド

レコードにファイルが添付されているかどうかで、trueかfalseを返すメソッドです。
ifと組み合わせて、画像の有無によって表示するかどうか判断させられます。

モデル.ファイル名.attached?
<%= image_tag message.image, class: 'message-image' if message.image.attached? %>

variantメソッド

ファイルの表示サイズを指定できます。

モデル.ファイル名.variant(resize: '幅x高さ')

記述例

html.erb
<div class="card">
  <%= link_to image_tag(prototype.image, class: :card__img ), prototype_path(prototype) if prototype.image.attached? %>
  <div class="card__body">
    <%= link_to "#{prototype.title}", root_path, class: :card__title%>
    <p class="card__summary">
      <%= "#{prototype.catch_copy}" %>
    </p>
    <%= link_to "by #{prototype.user.name}", root_path, class: :card__user %>
  </div>
</div>

画像かテキストだけのメッセージを送信

class Message < ApplicationRecord
  belongs_to :room
  belongs_to :user
  has_one_attached :image

  validates :content, presence: true, unless: :was_attached?

  def was_attached?
    self.image.attached?
  end
end

複数枚の投稿

アソシエーションの変更

has_one_attached :imageをhas_many_attached :imageへ変更

model.rb
class モデル名 < ApplicationRecord
  has_many_attached :images
end

フォームの修正

<%= form_with model: @モデル名, id: 'new_message', local: true do |f| %>
  <%= f.text_field :content, placeholder: 'type a message' %>
  <%= f.file_field :images, name: 'message[images][]', id: 'message_image' %>
  <%= f.submit '送信' %>
  <div id="image-list"></div>
<% end%>

ストロングパラメーターの修正

なお、配列型のパラメーターは最後に書かなければエラーを吐く。
エラーを吐く例:params.require(:モデル名).permit(images: [], :title)

controller.rb
private
  def message_params
    params.require(:モデル名).permit(images: [])
  end
end

ビューの修正

<%= image_tag @変数.image, id: 'image' if @変数.image.present? %>は削除し、以下の記述に置き換える。

html.erb
<% @変数.images.each do |image| %>
  <%= image_tag image, class: 'images' %>
<% end %>

仮に1番目の画像のみを表示したい場合は、以下の記述となる。

<%= image_tag @親モデル名.image.first %>
4
7
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
4
7