Rails6で追加 レコードを一括登録できるinsert_allについて

2021年9月22日水曜日

Rails

t f B! P L

 


insert_allの概要

rails6で追加された。複数レコードを一括登録できる。

insert_allドキュメント

insert_allの使い方

形としてはこんな感じ。

モデル.insert_all([{カラム: value...},{カラム: value...}...])

Task.insert_all([
  {user_name: "太郎", created_at:"2021/09/20 09:00", updated_at: "2021/09/20 09:00"},
  {user_name: "花子", created_at:"2021/09/20 09:00", updated_at: "2021/09/20 09:00"},
  ])

→発行されるSQLは1個だけ!うれしい⭐️
INSERT INTO "tasks" ("user_name","created_at","updated_at") VALUES ('太郎', '2021-09-20 09:00:00', '2021-09-20 09:00:00'), ('花子', '2021-09-20 09:00:00', '2021-09-20 09:00:00') RETURNING "id"

insert_allの注意点

created_at, updated_atは自動付与されないので未指定の時はエラーになる

ActiveRecord::NotNullViolation: PG::NotNullViolation: ERROR:  null value in column "created_at" of relation 

対策

  • 上に書いた例のようにデータ自体にcreated_at達を直接指定する。

  • マイグレーションファイルにtimestampのデフォルト指定する。多分これでできる。動作確認まではしていない
t.timestamps null: false, default: ->{ "CURRENT_TIMESTAMP" }

  • create_withを使う。全データにセットする必要がなくなってシンプルではある
Task.create_with(created_at:"2021/09/20 09:00", updated_at: "2021/09/20 09:00").insert_all([
  {user_name: "太郎"},
  {user_name: "花子"},
])

自己紹介

Webエンジニアをやっています。日々思ったことや、読書レビュー、IT系の記事などを書き連ねています

広告

Ruby mapでnilが入ってしまう件

  概要 ブロック内の結果を配列にして返すrubyのmap。 便利だが以下のように特定の値の時にスキップしたいケースでは、nilが入ってしまう ( 1 .. 5 ). map do | v | next if v == 3 v end => [ 1 , 2...

QooQ