CRUD を作成⑧
CRUD を作成⑦ の続き。
ブラウザからデータを登録できるか確認する。
作成ボタンを押す。一覧ページを見てみる。
先ほど登録した名前で一覧ページに表示されていれば登録できたことを確認できる。
登録後にどこかのページにリダイレクトするように修正する。
app/controllers/books_controller.rb を以下のように修正する。
def create
@book = Book.new(book_params)
if @book.save
redirect_to books_path
end
end
コードを変更したのでテストを実行する。
レッドになる。
...F...
Failures:
1) Books POST /books 正常系 204 を返す
Failure/Error: expect(response).to have_http_status(:no_content)
expected the response to have status code :no_content (204) but it was :found (302)
# ./spec/requests/books_spec.rb:38:in `block (4 levels) in <main>'
Finished in 0.34714 seconds (files took 2.83 seconds to load)
7 examples, 1 failure
Failed examples:
rspec ./spec/requests/books_spec.rb:36 # Books POST /books 正常系 204 を返す
リダイレクトするように修正したのでテストの期待値を変更する。
spec/requests/books_spec.rb を以下のように変更する。
describe "POST /books" do
let(:params) { { book: { title: } } }
let(:title) { 'test' }
context '正常系' do
it '302 を返す' do
post "/books", params: params
expect(response).to have_http_status(:found)
end
end
end
テストを実行する。グリーンになる。
bundle e rspec spec/requests/books_spec.rb
.......
Finished in 0.36111 seconds (files took 2.83 seconds to load)
7 examples, 0 failures
ブラウザからも試してみる。
作成ボタンを押した後、一覧ページにリダイレクトされたら成功。
次に、何も入力しない状態で作成ボタンを押してみる。データが空文字で作成されてしまう。これは許容したくないのでバリデーションを追加する。
app/models/book.rb を修正する。
class Book < ApplicationRecord
validates :title, presence: true
end
空文字ではデータを登録できないことを確認する。そのため、テストを追加する。
RSpec.describe Book, type: :model do
describe 'validation' do
subject { book.valid? }
context 'title が空文字の場合' do
let(:book) { build(:book) }
before { book.title = '' }
it { is_expected.to be false }
end
end
end
テストを実行する。グリーンになる。
bundle e rspec spec/models/book_spec.rb
.
Finished in 0.06566 seconds (files took 2.85 seconds to load)
1 example, 0 failures
空文字ではデータが登録できないことを担保できた。
何も入力していない状態で作成ボタンを押す。ログを見てみるとデータが登録されていないことがわかる。
バリデーションに引っかかった場合の処理をコントローラに追加する。
app/controllers/books_controller.rb を以下のように修正する。
def create
@book = Book.new(book_params)
if @book.save
redirect_to books_path
else
render :new
end
end
保存に失敗した場合は引き続き新規作成ページが表示される。
試しにN文字以上という制限をつけてみる。
テストを以下のように修正する。spec/models/book_spec.rb を以下のように修正する。今回は3文字以下で保存ができないようにする。
context 'title が3文字以下の場合' do
let(:book) { build(:book) }
before { book.title = 'ab' }
it { is_expected.to be false }
end
テストを実行する。当然、3文字以下というバリデーションを追加していないのでテストはレッドとなる。
bundle e rspec spec/models/book_spec.rb
.F
Failures:
1) Book validation title が3文字以下の場合 is expected to equal false
Failure/Error: it { is_expected.to be false }
expected false
got true
# ./spec/models/book_spec.rb:20:in `block (4 levels) in <main>'
Finished in 0.07983 seconds (files took 2.82 seconds to load)
2 examples, 1 failure
Failed examples:
rspec ./spec/models/book_spec.rb:20 # Book validation title が2文字以下の場合 is expected to equal false
3文字以下という制限を加えるため app/models/book.rb を修正する。
validates :title, presence: true, length: { minimum: 3 }
N文字以上のような制限を加える場合、境界値もテストしておきたい。3文字の場合もテストしてみる。
context 'title が3文字の場合' do
let(:book) { build(:book) }
before { book.title = 'abc' }
it { is_expected.to be true }
end
3文字の場合は許容される。テストコードが重複してきたのでリファクタを行う。
RSpec.describe Book, type: :model do
describe 'validation' do
subject { book.valid? }
context 'title が空文字の場合' do
let(:book) { build(:book) }
before { book.title = '' }
it { is_expected.to be false }
end
context 'title が3文字より少ない場合' do
let(:book) { build(:book) }
before { book.title = 'ab' }
it { is_expected.to be false }
end
context 'title が3文字の場合' do
let(:book) { build(:book) }
before { book.title = 'abc' }
it { is_expected.to be true }
end
end
end
spec/models/book_spec.rb を以下のように修正する。book という変数を3回定義していたので、1回にまとめた。
RSpec.describe Book, type: :model do
describe 'validation' do
subject { book.valid? }
let(:book) { build(:book) }
context 'title が空文字の場合' do
before { book.title = '' }
it { is_expected.to be false }
end
context 'title が3文字より少ない場合' do
before { book.title = 'ab' }
it { is_expected.to be false }
end
context 'title が3文字の場合' do
before { book.title = 'abc' }
it { is_expected.to be true }
end
end
end
これで3文字より少ない場合は保存に失敗するようになった。
実際に3文字より少ない場合で作成しようとすると保存されず、3文字以上の場合は作成される。
一覧ページから新規作成ページに遷移するためにリンクを追加する。
app/views/books/index.html.erb を以下のように修正。
<%= link_to '新規作成', new_book_path %><br />
ブラウザに表示をしてみて新規作成ページに遷移できることを確認する。
次は新規作成ページから一覧ページに戻れるよう、新規作成ページにリンクを追加する。
app/views/books/new.html.erb に以下のコードを追加する。
<%= link_to '一覧', books_path %>
これでスムーズに新規作成ページと一覧ページを行き来することができるようになった。
次に続く。
この記事が気に入ったらサポートをしてみませんか?