nullを理解していなかった話
内容が間違えていたので、修正しました
nullを理解しておらず、はまりました。
null
- 未定義であるということ
- 数字の0や空白とは違う
はまったこと
migrationのnot null制約は生成時のvalidationになります。
migrationのnot null制約は値がnullかどうかの判断になります。
対して、モデルのvalidatesは、保存時にないといけないという制約になります。
モデルのpresence: trueは、値が存在するかどうかの判断になります。
似ているけど、役割が違うということ。
Speaker classのmigration fileになります。
class CreateSpeakers < ActiveRecord::Migration def change create_table :speakers do |t| t.string :name, null: false t.string :type t.timestamps null: false end end end
nameはnot nullなんで、存在しないといけないから、次のようなテストは通るだろ?と考えてしまっていました。
FactoryGirl.define do factory :player do name Faker::Name.name end end
require 'rails_helper' RSpec.describe Player, type: :model do describe 'validation' do let(:player) { create(:player) } it 'nameは存在しないといけない' do player.name = '' expect(player).not_to be_valid end end end
これだとテストは通りません。
なぜなら、生成後の変更の存在はnot nullという条件ではないからです。
理由は**''がnilではなく、値として認識されているからです。
''.nil? => false
''.present? => false
なので、素直にpresence: trueを書かないといけません。
class Player < Speaker validates :name, presence: true end
これでテストが通ります。
違いがわかっておけば怖くない。
nullを全く理解していなかった話です。
個人的にrailsから入ったエンジニアは、sqlの知識が弱いと勝手に思っています。
sqlの知識をもっと身につけないとなー