💡
この記事は Middleman 時代に書いた古いものです。記録のため、astro-notion-blog に移行していますが、あまり参考にしないでください。
request spec による new のテストと実装
-
GET #new の spec を spec/requests/kurasus_spec.rb に記載する.new はレスポンスが 200 であることを確認できればよい.
describe 'GET #new' do subject { -> { get new_kurasu_path } } it_behaves_like :response_status_check, 200 end
-
GET #new の実装を app/controllers/kurasus_controller.rb に記載する.
def new @kurasu = current_teacher.kurasus.build(name: 'クラス名', obsolete: false) end
-
GET #new のビューを app/views/kurasus/new.html.haml に記載する. ここはタイトルの設定と _form の読み込みのみである.
- content_for :title do - @title = "#{t '.title'}: #{current_teacher.name}" = render partial: 'form', locals: {kurasu: @kurasu}
-
読み込まれる _form.html.haml は Rails 5.1 から導入された form_with を使う. これは new だけでなく edit からも読み込まれる. new の場合は,obsolete = false のものを作成するため,入力欄は表示せず hidden_field で渡す. html 5 からは autofocus は Javascript を使わずに設定できるようになっている.
- is_edit = controller.action_name == 'edit' = form_with model: kurasu, local: true do |f| %table %tr %th= f.label :name %td= f.text_field :name, autofocus: true - if is_edit %tr %th= f.label :obsolete %td= f.check_box :obsolete, {checked: kurasu.obsolete}, 'true', 'false' %tr %td{colspan: 2} - unless is_edit = f.hidden_field :obsolete = f.hidden_field :teacher_id = f.submit
request spec による create のテストと実装
-
POST #create の spec を spec/requests/kurasus_spec.rb に記載する.追加に成功する場合と失敗する場合の二種類を確認できればよい. 利用した shared_example は以下の通りである.
- increment_object_by_create: モデルが一つ追加されるか確認
- flash_notice_message: notice メッセージが設定されているか確認
- redirect_to: return_path にリダイレクトされるか確認
- not_increment_object_by_create: モデルが追加されないことを確認
- flash_alert_message: alert メッセージが設定されているか確認
describe 'POST #create' do before { @attrs = object.attributes; object.destroy } subject { -> { post kurasus_path(edit_mode: true), params: {kurasu: @attrs}} } context '正しいパラメータに対して' do it_behaves_like :response_status_check, 302 it_behaves_like :increment_object_by_create, Kurasu it_behaves_like :flash_notice_message, 'クラスを登録しました.' it_behaves_like :redirect_to end describe '不正なパラメータに対して' do before { @attrs['name'] = nil } it_behaves_like :response_status_check, 200 it_behaves_like :not_increment_object_by_create, Kurasu it_behaves_like :flash_alert_message, 'クラスが登録できません.' end end
-
POST #create の実装を app/controllers/kurasus_controller.rb に記載する. kurasu_params というメソッドにより params の属性のフィルタリングを行なっている(permit しない属性は無視される). また,notice_message, alert_message は DRY にするためにメソッド化している.
def create @kurasu = Kurasu.new(kurasu_params) if @kurasu.save redirect_to kurasus_path(edit_mode: true), notice: notice_message(Kurasu) else flash.now[:alert] = alert_message(Kurasu) render action: :new end end def kurasu_params params.require(:kurasu).permit(:teacher_id, :name, :obsolete) end private :kurasu_params
-
notice_message, alert_message は app/controllers/application_controller.rb に記載する. それぞれ,flash.create.notice, flash.create.alert から locale を取得するようになっている. また,update の時にも使えるように,create の部分は action_name から作成している.
def notice_message(klass) I18n.t "flash.#{action_name}.notice", {obj: klass.model_name.human} end def alert_message(klass) I18n.t "flash.#{action_name}.alert", {obj: klass.model_name.human} end
-
flash.{create, update}.{notice, alert} の locale を config/locales/views.ja.yml に追加しておく. また,次回作成する edit, update などの locale も一緒に作成しておく. locale にはこんな感じで引数が指定できる.
ja: flash: create: notice: "%{obj}を登録しました." alert: "%{obj}が登録できません." update: notice: "%{obj}を更新しました." alert: "%{obj}が更新できません." edit: alert: "%{obj}を編集する権限がありません." destroy: notice: "%{obj}を削除しました." alert: "%{obj}を削除する権限がありません." show: alert: "%{obj}を表示する権限がありません."
-
最終的な guard 出力はこんな感じになった(本日分のみ).全てテストが通過している.
GET #new behaves like response_status_check response should be 200 POST #create 正しいパラメータに対して behaves like response_status_check response should be 302 behaves like increment_object_by_create should change `Kurasu.count` by 1 behaves like redirect_to should redirect to "/kurasus?edit_mode=true" behaves like flash_notice_message should eq "クラスを登録しました." 不正なパラメータに対して behaves like response_status_check response should be 200 behaves like not_increment_object_by_create should not change `Kurasu.count` behaves like flash_alert_message should eq "クラスが登録できません."
長くなったので今日はここまで