#使用するツール
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高さ')
##記述例
<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へ変更
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)
private
def message_params
params.require(:モデル名).permit(images: [])
end
end
##ビューの修正
<%= image_tag @変数.image, id: 'image' if @変数.image.present? %>は削除し、以下の記述に置き換える。
<% @変数.images.each do |image| %>
<%= image_tag image, class: 'images' %>
<% end %>
仮に1番目の画像のみを表示したい場合は、以下の記述となる。
<%= image_tag @親モデル名.image.first %>