こんにちは。
最近、Railsでinsert_all
を使う機会があったのですが、その際に返り値に注意しないといけないことがあったので、その話をします。
insert_allの返り値
insert_all
は、その名の通り、複数のレコードを一度に挿入するためのメソッドです。
# 例としてUserモデルがあるとします。
# Userテーブルにはnameカラムとemailカラムがあるとします。
users = [
{ name: 'Alice', email: 'alice@example.com' },
{ name: 'Bob', email: 'bob@example.com' },
{ name: 'Charlie', email: 'charlie@example.com' }
]
result = User.insert_all(users)
# 結果の確認
puts result.inspect
このメソッドの返り値は、ActiveRecord::Resultオブジェクトです。
#<ActiveRecord::Result:0x00007f832d10b8c0
@columns=["id"],
@rows=[[1], [2], [3]],
@hash_rows=[{"id"=>1}, {"id"=>2}, {"id"=>3}],
@column_types={"id"=>#<ActiveModel::Type::Integer:0x00007f832c3ef508>}
>
このオブジェクトには、挿入されたレコードのIDが含まれています。
逆にいうと、ID以外のカラムの値は含まれていません。
そのため、insert_all
の返り値を使って、挿入されたレコードの情報を取得するには、別途クエリを発行する必要があります。
# 例として、挿入されたレコードの情報を取得するためのクエリを発行する
inserted_ids = result.rows.flatten
inserted_users = User.where(id: inserted_ids)
まとめ
insert_all
の返り値は、挿入されたレコードのIDのみを含んでいるため、挿入されたレコードの情報を取得するには別途クエリを発行する必要があります。
謎挙動じゃん…と思ってしまいましたが、そういうものだと覚えておくためにも、この記事を書いてみました。