rails5系以降はtimestampがデフォルトてNOT NULLだった

タイトル通りなのですが、rails5系以降はtimestampがデフォルトてNOT NULLだということを今日知りました。

 

4系まではnull: falseをつけないとNOT NULL制約を付けることができなかったようですが挙動が変わっていたようです。

 

 

こちらの記事に詳しく書かれておりました。

https://y-yagi.tumblr.com/post/137935511450/rails-5から導入されたmigration-versioingについて

 

 

 

感想その他

何もなくても制約つくのはありがたいですが少しわかりづらいw

CloudFrontのキャッシュ削除

今までCloudFrontのキャッシュ削除をしてくれるコマンドに頼っておりましたが、なぜか変更が反映されない現象が起きました。

そこでAWSのマネジメント画面から削除したのでその手順についてかいておきます!

 

やり方

1. AWSコンソールからCloudFrontのサービスを選択

 

2. 対象のリポジトリを選択

 

3. Invalidationsタブを選択

 

4. Create Invalidationsを選択

 

5. 入力欄に/*を入力し、 Invalidateをクリック

 

ここでHTMLファイルを指定したら消えなかったためキャッシュは変更があったHTML以外にもあるようです。

 

 

感想その他

キャッシュはどこに溜まるのか、何者なのか、よくわっていない。。

 

業務エラーとシステムエラー

エラーハンドリングするにあたって、まずは業務エラーとシステムエラーを分けて考える必要がありました。

両者の違いについてメモしておこうと思います!

 

業務エラー

バリデーションに引っかかるような、正しい値に直せば対応できるエラー。

 

 

システムエラー

DBが落ちてる、通信できない、データ不整合などのクライアント側で対応できないエラー。

 

 

感想その他

この2つをきちんと区別した上で、どんなエラーとして返すのか、返さないのか考えていかなくては!!

DBで設定できる制約

DBで設定できる制約について調べてみました〜

 

unique制約

同じ値は登録できない制約です。

 

 

not null制約

nullを登録できない制約です。

 

 
primary key制約

主キーを設定する制約です。

null、同じ値が保存できなくなります。

railsだとidにデフォルトでprimary key制約がつきます。

 

 

default制約

値を指定しなかった際のデフォルト値を設定する制約です。

 

 

foreign key制約

参照先のテーブルに無い値は保存できないようにする制約です。

 

 

感想その他

各種制約の詳しい内容についても後日調べたいです!

 

 

t.referencesとforeign_key: true

 テーブルを作成する際、外部キー周りの設定でt.referencesとforeign_key: trueが何をしてくれるのか・してくれないのか曖昧だったので調べました。

 

 t.references
  • 参照モデル名_idというカラム名で参照モデルのidと紐付けてくれる
  • これだけだと参照にないidでも登録できてしまう

 
foreign_key: :true

  • 外部キー制約をつけてくれる
  • dependent: :destroyつけないと親レコード消せない
  • indexが自動でつくので書かなくていい
  • 親レコードにない値は参照カラムに登録できない
  • 値がNULLでも挿入できてしまうため、別途null: :falseつける必要がある

 

感想その他

細かく把握しておかないといけないなと思いました。

 

 

 

where.not

アクティブレコードのwhere.notを使った実装を考えていたのですが、

where.notが変換されるSQL(WHERE ~ NOT IN)にはINの引数にNILLである値が含まれていると何も取得できないという注意点があるようなので、where.notでもそうなの?!と思い試してみました。

 

以下が試してみた内容です。

> Pet.where.not(id: [1,nil])

Pet Load (45.5ms)  SELECT  `pets`.* FROM `pets` WHERE NOT *1 LIMIT 11

=> #<ActiveRecord::Relation [#<Pet id: 2, name: "Puffball", owner: "Diane", species: "hamster", sex: "f", birth: "1989-08-31", death: "1995-07-29", created_at: "2019-11-04 09:28:57", updated_at: "2019-11-04 09:28:57">, #<Pet id: 3, name: "Bowser", owner: "Diane", species: "dog", sex: "m", birth: "1989-08-30", death: "1995-07-29", created_at: "2019-11-04 09:30:18", updated_at: "2019-11-04 09:30:18">, #<Pet id: 4, name: "Momiji", owner: "Hayashi", species: "dog", sex: "m", birth: "2003-08-12", death: nil, created_at: "2019-11-04 09:31:18", updated_at: "2019-11-04 09:31:18">, #<Pet id: 5, name: "Buffy", owner: "Nana", species: "dog", sex: "f", birth: "1991-10-10", death: nil, created_at: "2019-11-04 09:32:08", updated_at: "2019-11-04 09:32:08">, #<Pet id: 6, name: "chee", owner: "yoshino", species: "fish", sex: "f", birth: "1994-08-01", death: nil, created_at: "2019-11-09 13:57:26", updated_at: "2019-11-09 13:57:26">]>

 どうやらアクティブレコード側で対処してくれているようで、ちゃんとこちらの希望通りに取得できておりました。

 

 

感想その他

アクティブレコードのwhere.notについても、

SQLのWHERE ~ NOT INについてもまだよくわからない部分があるので引き続き調べてみようと思います!

 

 

 

 

*1:`pets`.`id` = 1 OR `pets`.`id` IS NULL

外部キー制約

外部キー制について考える機会があったのでメモしておきます〜

 

外部キー制約とは

外部キーは関連づけているテーブル間のデータの整合性を保つために存在する制約です。

外部キー制約を設定しておくと、存在しないidで外部キーを保存する事ができなくなります。

 

 

 

railsで外部キーを設定する

テーブル作成する時のマイグレーションファイルで外部キーとして設定したいカラムを以下のように設定します。

t.refernce  親モデル名, foreign_key: true

 

こうするとカラムは 親モデル名_id という名前で、外部キー制約が設定された状態で作成されます。

インデックスも貼ってくれます。

 

 

感想その他

モデルでバリデーションかけるとしても、データベースは必ず整合性の取れた状態であってほしいので、データベースレベルでの制約も必要ですね!!

自分が間違えてSQL実行してしまった場合にはモデルのバリデーションはあてになりませんし。。。