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

RailsApp Rails 2018年 12月 5日

ある程度一通りの機能が作れたため,その他のモデルを追加していく.

gakusei モデルの追加

  1. generator で gakusei モデルを作成する.
  2. $ bin/rails g model gakusei number:integer name:string kurasu_id:integer
    Running via Spring preloader in process 49533
          invoke  active_record
          create    db/migrate/20181202012847_create_gakuseis.rb
          create    app/models/gakusei.rb
          invoke    rspec
          create      spec/models/gakusei_spec.rb
          invoke      factory_bot
          create        spec/factories/gakuseis.rb
  3. db/migrate/*_create_gakuseis.rb を修正する. 各属性は null: false にすることと,kurasu_id, number の組に index を付けると共に,plural unique を設定する.
  4. class CreateGakuseis < ActiveRecord::Migration[5.2]
      def change
        create_table :gakuseis do |t|
          t.integer :number, null: false
          t.string :name, null: false
          t.integer :kurasu_id, null: false
          t.timestamps
        end
        add_index :gakuseis, %i[kurasu_id number], unique: true
      end
    end
  5. migrate する
  6. bin/rails db:migrate

gakusei_spec の記述

  1. spec/models/gakusei_spec.rb を修正する.
  2. require 'rails_helper'
    
    RSpec.describe Gakusei, type: :model do
    
      context 'common validation check' do
        subject { gakusei_factory :foo2301 }
    
        it_behaves_like :presence_validates, %i[number name kurasu_id]
        #it_behaves_like :unique_validates, %i[], -> { gakusei_factory :other }
        it_behaves_like :plural_unique_validates, %i[kurasu_id number], -> { gakusei_factory :baz3301 }
        it_behaves_like :destroy_validates
        it_behaves_like :belongs_to, :gakusei, has_many: %i[kurasu]
        it_behaves_like :dependent_destroy, :gakusei, %i[kurasu]
      end
    
      context 'after some gakuseis are registrered' do
        model_keys = %i[baz3301 bar2302 foo2301]
        let!(:targets) { gakusei_factories model_keys }
    
        describe 'Gakusei class' do
          subject { Gakusei }
    
          it_behaves_like :mst_block, -> t do
            {
              order_number: [nil, t.values_at(2, 1, 0)],
            }
          end
        end
    
        context 'Gakusei instances' do
          subject { targets }
    
          it_behaves_like :amst_block, -> t do
            {
              name: [nil, %w[baz bar foo]],
              number: [nil, %w[3301 2302 2301]],
            }
          end
        end
      end
    end

gakusei model の記述

  1. app/models/gakusei.rb を記載する.
  2. class Gakusei < ApplicationRecord
      validates :number, :name, :kurasu_id, presence: true
      validates :number, uniqueness: {scope: :kurasu_id}
      # @return [Kurasu] 対応するクラス
      belongs_to :kurasu
    
      scope :order_number, -> { order arel_table[:number] }
    end
  3. 関連する app/models/kurasu.rb に has_many を追加する.
  4. class Kurasu < ApplicationRecord
      (中略)
      # @return [Array<Gakusei>] 関連する学生一覧
      has_many :gakuseis, dependent: :destroy

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