📘 hkob-astro-notion-blog

これまではてなブログにて情報発信をしていましたが、令和5年3月22日より、こちらでの情報発信を始めました。2019年以前の古い記事は過去の Middleman 時代のものなので、情報が古いです。記録のためだけに残しています。

event モデルの作成 - 不定期刊 Rails App を作る(35)

💡
この記事は Middleman 時代に書いた古いものです。記録のため、astro-notion-blog に移行していますが、あまり参考にしないでください。

いよいよ最後のモデルを追加する.

event_gakusei モデルの追加
  1. generator で event モデルを作成する.
    $ bin/rails g model event_gakusei event_id:integer gakusei_id:integer shusseki:integer
    Running via Spring preloader in process 90585
          invoke  active_record
          create    db/migrate/20181223210805_create_event_gakuseis.rb
          create    app/models/event_gakusei.rb
          invoke    rspec
          create      spec/models/event_gakusei_spec.rb
          invoke      factory_bot
          create        spec/factories/event_gakuseis.rb
  2. db/migrate/*_create_event_gakuseis.rb を修正する. 各属性は null: false にすることと,event_id, gakusei_id の組に index を付けると共に,plural unique を設定する.
    class CreateEventGakuseis < ActiveRecord::Migration[5.2]
      def change
        create_table :event_gakuseis do |t|
          t.integer :event_id, null: false
          t.integer :gakusei_id, null: false
          t.integer :shusseki, null: false
          t.timestamps
        end
        add_index :event_gakuseis, %i[event_id gakusei_id], unique: true
      end
    end
  3. migrate する
    bin/rails db:migrate
event_spec の記述
  1. spec/models/event_gakusei_spec.rb を修正する.
    require 'rails_helper'
    
    RSpec.describe EventGakusei, type: :model do
    
      context 'common validation check' do
        subject { event_gakusei_factory :start_foo }
    
        it_behaves_like :presence_validates, %i[event_id gakusei_id shusseki]
        #it_behaves_like :unique_validates, %i[], -> { event_gakusei_factory :other }
        it_behaves_like :plural_unique_validates, %i[event_id gakusei_id], -> { event_gakusei_factory :hr_bar2302 }
        it_behaves_like :destroy_validates
        #it_behaves_like :reject_destroy_validates
        it_behaves_like :belongs_to, :event_gakusei, has_many: %i[event gakusei]
        it_behaves_like :dependent_destroy, :event_gakusei, %i[event gakusei]
        #it_behaves_like :reject_destroy_for_relations, :event_gakusei, %i[has_many has_one]
        #it_behaves_like :destroy_nullify_for_relations, :event_gakusei, %i[has_many has_one]
      end
    
      context 'after some event_gakuseis are registrered' do
        model_keys = %i[hr_baz3301 hr_bar2302 start_foo]
        let!(:targets) { event_gakusei_factories model_keys }
    
        describe 'EventGakusei class' do
          subject { EventGakusei }
    
          it_behaves_like :mst_block, -> t do
            {
              order_number: [nil, t.reverse],
            }
          end
    
          #it_behaves_like :msta_block, -> t do
          #  {
          #    method1: [v1, a1, v2, a2, ...],
          #    method2: [v1, a1, v2, a2, ...],
          #  }
          #end
          #it_behaves_like :mst, :METHOD1, -> { [v1, event_gakusei_factories(model_keys.values_at()), v2, event_gakusei_factories(model_keys.values_at())] }
          #it_behaves_like :msta, :METHOD1, -> { [v1, event_gakusei_factories(model_keys.values_at()), v2, event_gakusei_factories(model_keys.values_at())] }
        end
    
        context 'EventGakusei instances' do
          subject { targets }
    
          #it_behaves_like :amst_block, -> t do
          #  {
          #    method1: [v1, a1, v2, a2, ...],
          #    method2: [v1, a1, v2, a2, ...],
          #  }
          #end
          #
          #it_behaves_like :amsta_block, -> t do
          #  {
          #    method1: [v1, a1, v2, a2, ...],
          #    method2: [v1, a1, v2, a2, ...],
          #  }
          #end
          #it_behaves_like :amst, :METHOD1, -> { [v1, a1, v2, a2] }
          #it_behaves_like :amsta, :METHOD1, -> { [v1, a1, v2, a2] }
        end
      end
    end
event_gakusei model の記述
  1. app/models/event_gakusei.rb を記載する.これまでと異なるのは,shusseki を enum に設定したことである.この属性には :unsettled, :shusseki, :kesseki の値しか入らない(データベースには integer の数値が入る).
    class EventGakusei < ApplicationRecord
      enum shusseki: {unsettled: 0, shusseki: 1, kesseki: 2}
      validates :event_id, :gakusei_id, :shusseki, presence: true
      validates :gakusei_id, uniqueness: {scope: :event_id}
    
      # @return [Event] 関連するイベント
      belongs_to :event
      # @return [Gakusei] 関連するイベント
      belongs_to :gakusei
    
      scope :order_number, -> { joins(:gakusei).merge(Gakusei.order_number) }
    
    end
  2. 関連する app/models/event.rb に has_many を追加する.
  3. 同様に関連する app/models/gakusei.rb に has_many を追加する.
  4. guard の結果は以下のようになった.
    EventGakusei
      common validation check
        behaves like presence_validates
          should be valid
          when event_id is nil
            should not be valid
          when gakusei_id is nil
            should not be valid
          when shusseki is nil
            should not be valid
        behaves like plural_unique_validates
          when another object has same event_id, gakusei_id
            should not be valid
          when another object has at least one different keys(event_id, gakusei_id)
            should be valid
        behaves like destroy_validates
          should destroy
            should change `EventGakusei.count` by -1
        behaves like belongs_to
          when destroying event_gakusei
            event.event_gakuseis.count should decrease
            gakusei.event_gakuseis.count should decrease
        behaves like dependent_destroy
          when destroying event
            should be destroyed by dependency
          when destroying gakusei
            should be destroyed by dependency
      after some event_gakuseis are registrered
        EventGakusei class
          behaves like mst_block
    mst: order_number
            should receive above methods(mst)
    
    Finished in 0.55832 seconds (files took 1.3 seconds to load)
    12 examples, 0 failures

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