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}"
 enddef 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を使って、掲示板に画像をアップロードする

この記事が気に入ったらサポートをしてみませんか?