rails 画像アップロード機能の追加
今回は、画像を投稿するに当たって、carrier_waveとmini_magickを利用した。
・gemファイルに記述し、bundle installする。
gem 'carrierwave'
・アップローダークラスを作成する。
rails g uploader アップローダー名
rails g uploader board_image # 今回は掲示板作成時に、画像を表示させたいためboard_imageをつけた
ターミナル上で打った後、app/uploaders/board_image_uploader.rbが作成される。このファイルの中を少し編集を加える。
class BoardImageUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
# include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
(def store_dirはデフォルトで入っている)
# Provide a default URL as a default if there hasn't been a file uploaded:
def default_url
'board_placeholder.png'
end
(追加)
# Process files as they are uploaded:
# process resize_to_fit: [300, 200]
#
# def scale(width, height)
# # do something
# end
# Create different versions of your uploaded files:
# version :thumb do
# process resize_to_fit: [50, 50]
# end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_whitelist
%w[jpg jpeg gif png]
end
(追加)
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename
# "something.jpg" if original_filename
# end
end
追加したものを見てみる。
def default_url
'board_placeholder.png'
end
上記のものは、デフォルトでの画像を指定しており、プレビューでは最初にここで指定した画像が表示されます。
def extension_whitelist
%w[jpg jpeg gif png]
end
次に追加した上記のものは、アップロードできる拡張子を制限しています。
・アップロード画像のカラムを、Boardモデルに追加する。
rails g migration AddBoardImageToBoards
db/migrate/++++_add_board_image_to_boards.rb内に追加する
class AddBoardImageToBoards < ActiveRecord::Migration[5.2]
def change
add_column :boards, :board_image, :string
end
end
rails db:migrateしてデータベースに反映し、schema.rbで確認
ActiveRecord::Schema.define(version: ++++++++) do
create_table "boards", force: :cascade do |t|
t.string "title", null: false
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "board_image" # board_imageカラムを確認
t.index ["user_id"], name: "index_boards_on_user_id"
end
・モデルとアップローダークラスの関連付を行う。そのためにapp/models/board.rbに以下を追加する。
class Board < ApplicationRecord
mount_uploader :board_image, BoardImageUploader # この行を追加
belongs_to :user
validates :title, presence: true, length: { maximum: 255 }
class モデル名 < ActiveRecord::Base
mount_uploader [:カラム名], [アップローダークラス]
end
これでBoardモデルに、board_imageカラムとBoardImageUploaderを関連づける。
・viewファイルを編集する。app/views/boards/_form.html.erbに編集を加える。以下のコードを追加する。
<div class="form-group">
<%= f.label :board_image %>
<%= f.file_field :board_image, class: 'form-control mb-3', accept: 'image/*' %>
<%= f.hidden_field :board_image_cache %>
</div>
<div class='mt-3 mb-3'>
<%= image_tag board.board_image.url,
id: 'preview',
size: '300x200' %>
</div>
accept: 'image/*は、画像ファイル全般を指定している。例えば、video/*は動画ファイル全般を指す。
<%= f.hidden_field :board_image_cache %>
このコードは、バリデーションに通らず掲示板登録ができなかったときに、画像を保持しておく機能で、hidden_fieldに〇〇_cacheを指定しておく。
・参考
【Rails】 CarrierWaveチュートリアル
CarrierWaveを使って、掲示板に画像をアップロードする
この記事が気に入ったらサポートをしてみませんか?