Rails 画像投稿機能の導入
CarrierWaveとMiniMagickを使って画像を投稿できるようにしていきます。この2つはインストール済みということを前提にして進めていきます。
画像のアップローダーの作成
% rails g uploader image
を実行すると、app/uploadesディレクトリにimage_uploader.rbが作成されます。
アップローダーとモデルの紐付け
次に、作成したアップローダーと関連するモデルを紐付けます。Boardモデルのboard_imageカラムと紐付けることを仮定します。board_imageカラムはstring型で生成します。カラムの生成方法は、
rails g migration AddBoardImageToBoards board_image:string
を実行。
class Board < ApplicationRecord mount_uploader :board_image, ImageUploader end
これで紐付けが完了しました。 生成されたアップローダーにデフォルトの画像と、アップロード可能なファイルの種類を指定します。
class ImageUploader < CarrierWave::Uploader::Base def store_dir "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" end def default_url '〇〇.png' end def extension_whitelist %w(jpg jpeg gif png) end end
アップロード先のファイルを.gitignoreに登録しておきます。
/public/uploads
画像の設定
image_uploader.rb
を編集して、MiniMagick経由で画像のリサイズを行えるようにします。
class ImageUploader < CarrierWave::Uploader::Base include CarrierWave::MiniMagick process resize_to_fit: [300, 200] end
としてあげるとリサイズすることができます。
view側の記述
ラベルと画像投稿用のフォームを作ります。
<%= f.label :board_image,"サムネイル" %> <%= f.file_field :board_image %>
投稿が許可されるようにpermitするカラムの追加もします。
def board_params params.require(:board).permit(:title, :body, :user_id,:board_image) end
フォームに送信した画像を呼び出すには、
<%= image_tag board.board_image_url %>
で呼び出すことができます。
画像を保存しないときはデフォルトにしたい
def default_url '〇〇.png' end
これをimageアップローダーに記述していたため、画像を載せないときはデフォルトで、〇〇.pngが乗ることになる。
参考
https://techtechmedia.com/carrierwave-minimagick-image/ https://ecolotta.hatenablog.com/entry/2020/12/31/175419 https://note.com/hajime38/n/ne2650fdf4559
gem 'carrier_wave'の導入
gem 'carrier_wave'とは
ファイルアップロード用のgemです。gemfileに
gem 'carrierwave'
と記述し、
% bundle install
でインストールすることができます。
参考
gem 'mini_magick'の導入
gem 'mini_magick'とは
画像を加工してくれるgemです。使うためには、gemfileに
gem 'mini_magick'
と記述し、
% bundle install
を実行するとインストールできます。さらに、MiniMagickをしようするためには、ImageMagickというものが必要になるため、これもインストールしましょう。
% brew install imagemagick
これでMiniMagickが使えるようになりました。
MiniMagickでできること
MiniMagickでできることは画像処理のあれこれです。
- 画像サイズ変更
- 画像反転
- 画像回転
- 画像フォーマット変換
- 色調整
- グラデーション
など様々な画像処理を行えます。
参考
M1macでrbenvを使ってrubyのインストール
% rbenv install 2.6.3
などrubyのバージョンをインストールしたいときにBUILD FAILEDが出てしまってインストールできないことがある。 そんなときはこれ!
% RUBY_CFLAGS=-DUSE_FFI_CLOSURE_ALLOC rbenv install 2.6.3
なんかわからないけどインストールできる。神
errorメッセージを個別で出したい
色々と調べながらやってるうちに知らない間にerrorメッセージを出せるようになってしまったが、やったことに自分の頭がついていっていないので、落ち着いてまとめてみる。
エラーメッセージ用のテンプレートの作成
まずはじめに全てのエラーメッセージを配列で取得します。が、エラーメッセージ用の部分テンプレートを作成するのが先です。いろいろなところで使うので、viewに書き込むと直すのが手間になってしまいます。views/shared/_error_messages.html.erb
としておきましょう。
<% if model.errors.any? %> <div class="alert alert-warning"> <ul> <% model.errors.full_messages.each do |message| %> <li><%= message %></li> <% end %> </ul> </div> <% end %>
さて、上のように書くことで、エラーメッセージを配列で取得でき、複数のエラーメッセージがある可能性がある(自分で作っていれば)ので、eachを使って、全て取得します。一行ずつ丁寧にみていきます。
- エラーメッセージ用のテンプレートの作成
- 1行目 <% if model.errors.any? %>
- 4行目 <% model.errors.full_messages.each do |message| %>
- 参考
1行目 <% if model.errors.any? %>
<% if model.errors.any? %>
errors.any?
はエラーがあるかどうかの真偽を出してくれるメソッドです。じゃあ、model
は?というと、呼び出す先で指定しているものになります。呼び出し先をviews/users/new.html.erbとでもしましょう。
<%= form_with model: @user, local: true do |f| %> <%= render 'shared/error_messages', model: f.object %> ...
<%= render 'shared/error_messages', model: f.object %>
の部分で呼び出しをしていて、model: f.object
のmodel
の部分が、<% if model.errors.any? %>
のmodelと対応しています。では、f.object
ってなんだろう?ということで調べていきます。
model: f.objectとは
f
はフォームビルダー変数といい、
<%= form_with model: @user, local: true do |f| %>
form_with
で生成された|f|
の部分です。このフォームビルダー変数には様々なメソッドがあり、text_field
(一行のテキスト投稿フォーム)やselect
(選択肢を作成)など様々ある。f.object
には、入力したデータが入っています。つまり、model: @user
の情報をもっていることになるので、userコントローラーのnewアクションとつながっていることになる。かなり遠いところまで行くけど、そういうことみたい。
4行目 <% model.errors.full_messages.each do |message| %>
まず、はじめのmodel
には、呼び出し先の
<%= form_with model: @user, local: true do |f| %>
の@userが代入されます。そして、errorsメソッドで@userの持っているエラーを表示してくれ、full_messages
でエラーの文章のみを配列で表示してくれます。そして、each do |message|
でエラーの配列を一つ一つ処理してくれる、というようになっているようです。
これでエラーメッセージが個別で出る動きが分かった。難しい。
参考
https://yama2-0506.hatenablog.com/entry/2020/12/11/083007 https://qiita.com/ryuuuuuuuuuu/items/1a1e53d062bff774d88a
Railsでデータベースのリセットをしよう!
データベースを空にするために、
rails db:reset
と
rails db:migrate:reset
の2種類存在する。この2つについて考えていきます。
rails db:resetとは
rails db:reset
は2種類のコマンドを実行するのと同じ働きがあります。
上の2種類のコマンドを実行するのと同等なので、一度データベースを削除して、スキーマからテーブルを再度作成し、シードデータを用いてデータベースの初期化を実行します。
rails db:migrate:resetとは
rails db:migrate:reset
では、DBの削除、DBの作成、rails db:migrate
が行われます。なので、seeds.rbの読み込みがないため、ダミーデータのようなものは作成されません。
どちらを使うか
seeds.rbの読み込みまでしたい場合は、rails db:reset
読み込みまではしたくない場合は、rails db:migrate:reset
ということになる。
参考
https://k-koh.hatenablog.com/entry/2020/09/25/232829 https://railsguides.jp/active_record_migrations.html https://note.com/kentarotawara/n/n976705aa4cb8 https://railsdoc.com/rake#rake_db_migrate