🖼️
画像投稿できるようにする
🍍画像投稿を1種類しか用いない時
今回の場合はUserのプロフィール投稿の時しか画像を表示しなくていいので以下の流れで行えばOK
1ActiveStorageをインストール
画像は通常のカラムとして保存できないためActiveStorageを入れることで画像の投稿や表示が行えるようになる。
rails active_storage:install
インストールが終わるとdb/migrate内にActiveStorageのマイグレーションファイルが追加される。
以下コマンドでmigrateを行う
rails db:migrate
2モデルに記述を追加
ActiveStorageを使って画像を表示する時には、どのモデルに対して画像を使うのかを宣言する必要がある。
例えば
- Userのプロフィールとしての画像を表示させたい→Userモデルに対して画像を使うのでUserモデルに記述
- 商品紹介の際に画像もつけて投稿したい→Item(商品)モデルに記述
使用したいモデルに対して下記記述を行う
今回はBookの画像を表示したいと仮定して進める。
model/user.rb
has_one_attached :image
3画像投稿ボタンの記述を追加
<%= f.file_field :image, accept: "image/*" %>
4コントローラ
事前に文字の投稿機能を作成している場合はparamsにimageを追加するだけ。
controller
books_controller.rb
def new
@book = Book.new
# 空のリストを作成
end
def create
book = Book.new(list_params)
# 新しいデータを受け取りストロングパラメータにかける
book.save
# 新しいデータをデータベースに保存
redirect_to
# 指定した画面へ、リダイレクトさせる
end
5画像を表示する
viewに以下を記述する
views/books/〇〇.html.erb
<% if user.image.attached? %>
<%= image_tag book.image, size: "200x200" %>
<% else %>
<%= image_tag 'no_image', size: "200x200" %>
<% end %>
これで画像を表示することはできるようになったが、この記述の仕方だと画像を表示する際に毎回同じ記述を書く必要があるので別の記述の仕方を行う。
モデルに記述を追加
model/book.rb
def get_image(width, height)
unless image.attached?
file_path = Rails.root.join('app/assets/images/no_image.jpg')
image.attach(io: File.open(file_path), filename: 'default-image.jpg', content_type: 'image/jpeg')
end
image.variant(resize_to_limit: [width, height]).processed
end
画像が登録されていない場合のエラーを回避するために画像が登録されているときとされていないときそれぞれを記述している。
ビュー
views/books/〇〇.html.erb
<%= image_tag book.get_post_image(100,100) %>
モデルに記述することでこの一文だけで表示できるようになる。
🍍画像投稿を2種類行うとき
インスタグラムのようにユーザープロフィールに加えて、投稿する際にも画像を表示するとき。
流れはほとんど一緒。
どうすればいいかというと
🍍エラー
Generating image variants require the image_processing gem. Please add gem 'image_processing', '~> 1.2'
to your Gemfile
解決
gemファイルを追加してくれと言われているので、
gemファイルの指示されている行をコメントアウトする。
bundle install
そしてbundle install
したらOK
Discussion