Rails1週目: modelの設計、複合ユニークのテストetc
はじめに
8/3 ~ 8/7に経験した内容をまとめる。Railsを触り始めて初週だったのもあって、インプットメインという感じだったが、助けを借りながらモデルを二つ実装した。
そのなかでも、validation、複合ユニークのテスト(RSpec)の書き方など、今後のために覚えておきたいことを殴りがいておく。
モデル名とかカラム名は適当にぼやかしてかいている。
もし間違いなどがあれば指摘していただけると嬉しい。
model作成のコマンド
今回作成したmodelでは外部キー(ForeignKey)の設定が必要だったのでreferencesを使った。
rails g model Stock company:references price:integer month:integer day:integer
最初accountのところをcompany_id:referenceとやってうまくいかなかった。
_idをつけなくても上記コマンドを打てばカラムにcompany_idが入る仕様になっているようだ。
複合ユニーク
migrationファイルに下記を実装する。
add_index :stocks, [:company_id, :month, :day], unique: true
modelのユニークの設計1
最初price含めてユニークにしまっていたのだが、
「それだと間違って二回集計されたときに金額が違うと、二重でレコードができてしまう」
というのをレビューで言われ、なるほどなーとなった。
ちなみに一回rails db:migrate
した後、migrationファイルを編集したら、
rails db:migrate:reset
このコマンドを打てばよい。 ただ、masterにマージされているモデルの編集の場合は、migrationコマンドでファイルを使って、それを使って編集していく。
migrationが終わったら、モデルファイルに下記のようにvalidationを実装する。
validates :company_id, uniqueness: { scope: %i[month day] }
modelのユニークの設計2
今回はpay_idとpay_history_idをFKとして中間テーブルを作ったのですが、
最初はこの二つに複合ユニークを貼ってたのですが
「「一つの集計に同じpay_idが複数回ふくまれない事」が保証できてるとおもうので、
「同じpay_idがが複数回他の集計に含まれない事」を保証するために pay_id 自体もUniqueインデックスをはってください」
とレビューで指摘された。
これもなるほどな、となった。
modelにvalidates :pay_id, uniqueness: true
を実装した。
今後こういう設計をするときユニークをうまく実装できるようにしたい。
複合ユニークのテスト(RSpec)
上記の中間テーブルの中の複合ユニークをテストの実装をした。
こういう時はユニークにならないようにcreate
やbuild
をしてfalseになるようにする。
let!(:pay) { create(:pay) } let!(:pay_history) { create(:pay_history) } it 'should be false with non unique index pay_id and pay_history_id' do create(:pay_year, pay: pay, pay_history: pay_history) invalid_pay_year = build(:pay_year, pay: pay, pay_history: pay_history) expect(invalid_payslip_delivery_entry.valid?).to be false end
来週に向けて
これを進めておく。