掲示板画像アップロード機能を作る
アップローダーの作成
$ bundle exec rails g uploader BoardImage
デフォルトの画像ファイルとアップロード可能なファイルの種類を指定する
class BoardImageUploader < CarrierWave::Uploader::Base # carrierwaveを通じた画像のアップロード先をどこにするのかを指定して、指定されたディレクトリに、アップロードされたファイルが保存されていく def store_dir "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" end # 画像が投稿されていない場合でもデフォルト画像を表示させる(uploaders/board_image_uploder.rb内の画像をデフォルトにする) def default_url 'board_placeholder.png' end # アップロード可能なファイル種別を指定 def extension_whitelist %w(jpg jpeg gif png) end end
アップロード先のフォルダを、.gitignoreに指定
/public/uploads
ローカルでアップした画像ファイルをリモートにアップロードしないようにgitignoreを追記
Boardテーブルに画像のカラムを追加する
Boardにboard_imageを追加
$ bundle exec rails g migration AddBoardImageToBoards board_image:string $ bundle exec rails db:migrate
Boardモデルに、アップローダーの仕様を宣言
class Board < ApplicationRecord mount_uploader :board_image, BoardImageUploader #追記 belongs_to :user validates :title, presence: true, length: { maximum: 255 } validates :body, presence: true, length: { maximum: 65_535 } end
ControllerとViewに、画像ファイルのフィールドを追加する
コントローラで、画像ファイルの入力を受け付ける
app/controllers/boards_controller.rb # reqireでデータのオブジェクト名を指定して、permitで保存処理のできるキーを追加する def board_params params.require(:board).permit(:title, :body, :board_image, :board_image_cache) end
掲示板のフォームに、画像ファイルの入力フィールドを追加
app/views/boards/_form.html.erb <%= form_with model: board, local: true do |f| %> <%= render 'shared/error_messages', object: f.object %> <div class="form-group"> <%= f.label :title %> <%= f.text_field :title, class: 'form-control' %> </div> <div class="form-group"> <%= f.label :body %> <%= f.text_area :body, class: 'form-control', rows: 10 %> </div> <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> <%= f.submit class: 'btn btn-primary' %> <% end %>
掲示板の部分テンプレートに、アップロードした画像のURLを指定
app/views/boards/_board.html.erb <div class="col-sm-12 col-lg-4 mb-3"> <div id="board-id-<%= board.id %>"> <div class="card"> <%= image_tag board.board_image_url, class: 'card-img-top', size: '300x200' %> <div class="card-body"> <h4 class="card-title"> <a href="#"> <%= board.title %> </a> </h4> <div class='mr10 float-right'> <a href="#"><%= icon 'fas', 'trash', class: 'pr-1' %></a> <a href="#"><%= icon 'fa', 'pen' %></a> </div> <ul class="list-inline"> <li class="list-inline-item"> <%= icon 'far', 'user' %> <%= board.user.decorate.full_name %> </li> <li class="list-inline-item"> <%= icon 'far', 'calendar' %> <%= l board.created_at, format: :long %> </li> </ul> <p class="card-text"><%= board.body %></p> </div> </div> </div> </div>
メッセージを追加
config/locales/activerecord/ja.yml ja: activerecord: attributes: board: title: 'タイトル' body: '本文' board_image: 'サムネイル'
config/locales/carrierwave/ja.yml ja: errors: messages: carrierwave_processing_error: '処理できませんでした' carrierwave_integrity_error: 'は許可されていないファイルタイプです' carrierwave_download_error: 'はダウンロードできません' extension_whitelist_error: "は %{allowed_types}の形式でアップロードしてください" extension_blacklist_error: "%{extension}ファイルのアップロードは許可されていません。アップロードできないファイルタイプ: %{prohibited_types}" content_type_whitelist_error: "%{content_type}ファイルのアップロードは許可されていません。アップロードできるファイルタイプ: %{allowed_types}" content_type_blacklist_error: "%{content_type}ファイルのアップロードは許可されていません" rmagick_processing_error: "rmagickがファイルを処理できませんでした。画像を確認してください。エラーメッセージ: %{e}" mini_magick_processing_error: "MiniMagickがファイルを処理できませんでした。画像を確認してください。エラーメッセージ: %{e}" min_size_error: "を%{min_size}以上のサイズにしてください" max_size_error: "を%{max_size}以下のサイズにしてください"