#はじめに
RSpecでモデルテストを書いている時にActiveStorageでモデルに関連づけた画像のバリデーションのところでつまづいたのでメモ。
RSpecとFactoryBotを使用する。(ここではインストールの部分は省略)
##やること
音楽レビューアプリのRecordモデルに付けた画像(:jacket
)が空の時はエラーを表示する。
#モデル
RecordモデルはGenreモデルに紐づいている。
Genreモデルは、(一部省略)
class Genre < ApplicationRecord
has_many :records
end
Recordモデルは、(一部省略)
class Record < ApplicationRecord
belongs_to :genre
has_one_attached :jacket #一つの画像
validate :jacket_presence #画像のバリデーション
def jacket_presence
unless jacket.attached?
errors.add(:jacket, 'must be attached')
end
end
end
has_one_attached :jacket
で一つの画像を持つとし、
jacket_presence
メソッドで画像が付いていない時はエラーメッセージを追加する。
#テスト用画像の用意
まずpublic
ディレクトリにjackets
ファイルを追加し、
そこに一つ画像を追加する。
ここではjustin.jpg
ファイルをpublic/jackets
に追加。
#FactoryBotを編集
まずはGenre
を編集する。
FactoryBot.define do
factory :genre do
name { "Pop" }
end
end
次はRecord
を編集する。
FactoryBot.define do
factory :record do
name { "Justice" }
release_year { 2021 }
artist { "Justin Bieber" }
#genreとのアソシエーションは、
#genre_id { 1 } でなく、以下のように書く
genre
#recordモデル作成後:jacketを関連づける。
after(:build) do |record|
record.jacket.attach(io: File.open('public/jackets/justin.jpg'), filename: 'justin.jpg')
end
end
end
これでテスト用のモデル作成の準備が完了。
#テストファイルの編集
Record
のモデルテストを編集する。
require 'rails_helper'
RSpec.describe Record, type: :model do
describe 'create new record'do
before do #テスト用のRecordを作成
genre = FactoryBot.create(:genre)
@record = FactoryBot.create(:record)
end
#全ての項目があれば有効。
context 'with a name, release_year, artist, genre, and jacket' do
it "is valid" do
record = @record
expect(record).to be_valid
end
end
#:jacketなしの場合はエラー
context 'without a jacket' do
it "is invalid" do
@record.jacket = nil #:jacketを空にする。
record = @record
record.valid?
#エラーメッセージが追加される。
expect(record.errors[:jacket]).to include("must be attached")
end
end
end
end
Record
はGenre
に紐づいているため先にgenre
を作成している。
これでテストできた。