carrierwaveを使った画像アップロード

CarrierWaveとは

railsアプリに簡単に画像をアップロードできるライブラリ

使い方

Gemfileに以下を記述して、bundle install

gem 'carrierwave', '~> 2.0'

その後、以下を実行することで、アップローダーファイルが生成される
今回はファイル名をBoard_imageとすると

bundle exec rails g uploader Board_image

を実行することで、app/uploaders/board_image_uploader.rbが生成される

class BoardImageUploader < CarrierWave::Uploader::Base
  storage :file
  
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  def default_url
    'board_placeholder.png'
  end
  
  def extension_whitelist
    %w[jpg jpeg gif png]
  end
end

ここにアップロードするファイルのカスタム設定を記述できる
store_dirではアップロードされたファイルの保存先を指定している
default_urlでは、何もファイルが指定されなかった時のデフォルトファイルを指定している
extension_whitelistではアップロードに選択できるファイルのフォーマットを指定できる
次に、今回は掲示板(Board)に画像用のカラム(board_image)を追加するので、

bundle exec rails g migration add_board_image_to_boards board_image:string
bundle exec rails db:migrate

を実行して、bundle exec rails db:migrate
次に画像用のカラムとuploaderファイルを関連づけるためにboard.rbに

mount_uploader :board_image, BoardImageUploader

を記述
掲示板フォームに画像アップロードフォームを追加

<%= form_with(model: board,local: true,class: 'form-group') do |form| %>
  <%= render 'shared/error_messages', object: form.object %>
  <div class="form-group">
    <%= form.label :title %>
    <%= form.text_field :title,class: 'form-control' %>
  </div>
  <div class="form-group">
    <%= form.label :body %>
    <%= form.text_area :body,class: 'form-control',rows: 10 %>
  </div>
  <div class="form-gruop">
    <%= form.label :board_image %>
    <%= form.file_field :board_image,class: 'form-control'%>
    <%= form.hidden_field :board_image_cache %>
  </div>
  <% form.submit "投稿する" %>
<% end %>

<%= form.hidden_field :board_image_cache %>は
例えば記載しないと掲示板の投稿に失敗した時、アップロードに選択したファイルが消えてしまうので、アップロードに失敗した際もファイルが消えないようにするため
boardsコントローラでストロングパラメータにboard_image、board_image_cacheを追記

def board_params
  params.require(:board).permit(:title, :body, :board_image, :board_image_cache)
end

これにより画像アップロードができるようになる!!

参考文献

GitHub - carrierwaveuploader/carrierwave: Classier solution for file uploads for Rails, Sinatra and other Ruby web frameworks

[Rails6.0.2]CarrierWaveを基本に忠実に使ってみる | ゆるりエンジニア

Rails CarrierWaveを使った画像投稿機能の実装メモ|ひびきき|note