events コントローラの作成(1) - 不定期刊 Rails App を作る(30)

RailsApp Rails 2018年 12月 17日

kurasus/events のコントローラは kurasus/gakuseis とほぼ同様である.

events コントローラの追加

  1. generator で kurasus/events コントローラを作成する.
  2. $ bin/rails g controller kurasus/events
    Running via Spring preloader in process 33998
          create  app/controllers/kurasus/events_controller.rb
          invoke  haml
          create    app/views/kurasus/events
          invoke  rspec
          invoke  assets
          invoke    js
  3. generator で integration_test を作成する. ただし,kurasus/events で作成すると,雛形が kurasus_events というモデルに対するものを作成してしまった. そこで,events で spec を作成後にフォルダを移動することにする.
  4. $ bin/rails g integration_test event
    Running via Spring preloader in process 34111
          invoke  rspec
          create    spec/requests/events_spec.rb
  5. events_spec.rb を spec/requests/kurasus の下に移動する.
  6. mv spec/requests/events_spec.rb spec/requests/kurasus
  7. routes に kurasus/events の項目を追加する.
  8. Rails.application.routes.draw do
      (中略)
      resources :kurasus do
        resources :events, controller: 'kurasus/events'
      end

events_spec の記述(index のみ)

  1. spec/requests/kurasus/events_spec.rb を修正する. ひな形からほぼ自動で作成されるので,index 以外の場所を if false で実行しないようにしておく.
  2. require 'rails_helper'
    
    RSpec.describe :Events, type: :request do
      include Devise::Test::IntegrationHelpers
    
      let!(:object) { event_factory :start2300_0406 }
      let!(:others) { event_factory :hr2300_0406 }
      let(:not_mine) { event_factory :hr3300_0413 }
      let(:kurasu) { object.kurasu }
      let(:return_path) { kurasu_events_path(kurasu, edit_mode: true) }
      context 'login by hkob' do
        teacher_login :hkob
    
        describe 'GET #index' do
          context 'normal mode' do
            subject { -> { get kurasu_events_path(kurasu) } }
            it_behaves_like :response_status_check, 200
            it_behaves_like :response_body_includes, %w[イベント一覧: 2300 編集モードに入る]
            it_behaves_like :response_body_not_includes, '3300'
          end
    
          context 'edit mode' do
            subject { -> { get kurasu_events_path(kurasu, edit_mode: true) } }
            it_behaves_like :response_status_check, 200
            it_behaves_like :response_body_includes, %w[イベント一覧: イベント作成]
          end
        end
    
        if false
        (中略)
        end
      end
    
      context 'not login' do
        describe 'GET #index' do
          subject { -> { get kurasu_events_path(kurasu) } }
          it_behaves_like :response_status_check, 302
          it_behaves_like :response_body_not_includes, %w[イベント一覧]
        end
      end
    end

kurasus/events_controller の記述(index のみ)

  1. app/controllers/kurasus/events_controller.rb を記述する.
  2. class Kurasus::EventsController < ApplicationController
      before_action :authenticate_teacher!
      before_action :get_kurasu
      before_action :get_one, only: %i[edit update destroy show]
    
      def index
        redirect_to(kurasus_path, alert: t('.not_my_kurasu')) and return if @kurasu.nil?
        @edit_mode = true if params[:edit_mode]
        @kurasus = current_teacher.kurasus.order_name
        @events = @kurasu.events.order_date_desc_sort_order
      end
    
      def get_kurasu
        @kurasu = current_teacher.kurasus.find_by_id(params[:kurasu_id])
      end
      private :get_kurasu
    
      def get_one
        @event = @kurasu.events.find_by_id(params[:id]) if @kurasu
      end
      private :get_one
    end

index の view を作成(後日,12/21 に修正する)

  1. app/views/kurasus/events/index.html.haml を記述する.
  2. - content_for :title do
      - @title = "#{t '.title'}: #{@kurasu.try(:name)}"
    
    %table
      %caption
        - if @edit_mode
          = link_to t('kurasus.events.new.title'), new_kurasu_event_path(@kurasu)
        - else
          = link_to t('enter_edit_mode'), kurasu_events_path(@kurasu, edit_mode: true)
      %thead
        %tr
          - t_ars(Event, %i[date sort_order]).each do |w|
            %th= w
          %th= t('control')
      %tbody
        - @events.each do |e|
          %tr
            %td= md_by_date e.date
            %td= e.sort_order
            %td
              = link_to t('kurasus.events.show.title'), kurasu_event_path(@kurasu, e)
              - if @edit_mode
                = link_to t('kurasus.events.edit.title'), edit_kurasu_event_path(@kurasu, e)
                = link_to t('.destroy'), kurasu_event_path(@kurasu, e), method: :delete, data: {confirm: t('.confirm')}
    
    = t '.select_kurasu'
    %table
      %tbody
        - @kurasus.each do |k|
          %tr
            %td= link_to k.name, kurasu_events_path(k, edit_mode: @edit_mode.presence)

locale 文字列の用意

  1. view には locale 用のキーワードしか書いていないので,それらの文字列を config/locales/views.ja.yml に追加しておく.
  2. ja:
      kurasus:
        events:
          index:
            title: イベント一覧
            select_kurasu: クラス選択
            destroy: イベント削除
            confirm: イベントを削除してよろしいですか?
            not_my_kurasu: このクラスは担当していません.
          show:
            title: イベント表示
          new:
            title: イベント作成
          edit:
            title: イベント編集

guard の結果

  1. guard の結果は以下のようになった
  2. Events
      login by hkob
        GET #index
          normal mode
            behaves like response_status_check
              response should be 200
            behaves like response_body_includes
              response body includes ["イベント一覧:", "2300", "編集モードに入る"]
            behaves like response_body_not_includes
              response body does not include 3300
          edit mode
            behaves like response_status_check
              response should be 200
            behaves like response_body_includes
              response body includes ["イベント一覧:", "イベント作成"]
      not login
        GET #index
          behaves like response_status_check
            response should be 302
          behaves like response_body_not_includes
            response body does not include ["イベント一覧"]

長くなったので今日はここまで