1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

お題は不問!Qiita Engineer Festa 2024で記事投稿!
Qiita Engineer Festa20242024年7月17日まで開催中!

Rails 7.2 をちょこっと試す (insert_all returning オプション編 (ただしMariaDBに限る))

Posted at

はじめに

Rails 7.2 では、MariaDB で、insert_allreturning オプションが使えるようになりました。
MySQL では使えないので注意が必要です。
(PostgreSQL では、以前から returning オプションが使えます。)

環境

  • Ruby 3.3.2
  • Rails 7.2.0.beta2
  • MariaDB 11.4.2
  • MySQL 8.4.0

準備

Bookモデルを作ります。

$ bin/rails g model Book title

MySQL での挙動

MySQL では returning オプションを使うとエラーになります。
MySQL に接続するように config/database.yml を修正して以下を実行します。

$ bin/rails db:create db:migrate

Rails コンソールで insert_all:returning実行するとエラーになります。

$ bin/rails c
sandbox(dev)> Book.insert_all([{id: 1, title: 'Programming Ruby'}], returning: %w[id title])
(sandbox):1:in `<main>': ActiveRecord::ConnectionAdapters::Mysql2Adapter does not support :returning (ArgumentError)

          raise ArgumentError, "#{connection.class} does not support :returning"
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

ちなみに、returning オプションを使わない場合は、 @rows[]ActiveRecord::Result が返ります。

sandbox(dev)> Book.insert_all([{id: 1, title: 'Programming Ruby'}])
  Book Insert (2.7ms)  INSERT INTO `books` (`id`,`title`,`created_at`,`updated_at`) VALUES (1, 'Programming Ruby', CURRENT_TIMESTAMP(6), CURRENT_TIMESTAMP(6)) AS `books_values` ON DUPLICATE KEY UPDATE `id`=`books_values`.`id`
=>
#<ActiveRecord::Result:0x0000ffff902bf738
 @column_indexes=nil,
 @column_types={},
 @columns=[],
 @hash_rows=nil,
 @rows=[]>

MariaDB での挙動

MariaDB では、returning オプションを使うと、 ActiveRecord::Result が返ります。

MariaDB に接続するように config/database.yml を修正して以下を実行します。

$ bin/rails db:create db:migrate

Rails コンソールで insert_all:returningオプションつきで、実行すると、 ActiveRecord::Result が返ります。

sandbox(dev)> Book.insert_all([{id: 1, title: 'Programming Ruby'}], returning: %w[id title])
  Book Insert (1.0ms)  INSERT INTO `books` (`id`,`title`,`created_at`,`updated_at`) VALUES (1, 'Programming Ruby', CURRENT_TIMESTAMP(6), CURRENT_TIMESTAMP(6)) ON DUPLICATE KEY UPDATE `id`=`id` RETURNING `id`,`title`
    =>
#<ActiveRecord::Result:0x0000ffff843cf468
 @column_indexes=nil,
 @column_types={},
 @columns=["id", "title"],
 @hash_rows=nil,
 @rows=[[1, "Programming Ruby"]]>

ちなみに returning オプションを省略した場合は、 id の情報だけの ActiveRecord::Result が返ります。

sandbox(dev)> Book.insert_all([{id: 2, title: 'Rails development'}])
  Book Insert (1.1ms)  INSERT INTO `books` (`id`,`title`,`created_at`,`updated_at`) VALUES (2, 'Rails development', CURRENT_TIMESTAMP(6), CURRENT_TIMESTAMP(6)) ON DUPLICATE KEY UPDATE `id`=`id` RETURNING `id`
    =>
#<ActiveRecord::Result:0x0000ffff84254340
 @column_indexes=nil,
     @column_types={},
     @columns=["id"],
     @hash_rows=nil,
     @rows=[[2]]>

Rails 7.1 での挙動

Rails 7.1 では、returning オプションを使うとエラーになります。

irb(main):001> Book.insert_all([{id: 1, title: 'Programming Ruby'}], returning: %w[id title])
(irb):1:in `<main>': ActiveRecord::ConnectionAdapters::Mysql2Adapter does not support :returning (ArgumentError)

          raise ArgumentError, "#{connection.class} does not support :returning"
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

まとめ

  • Rails 7.2 では、MariaDB で insert_allreturning オプションが使えるようになりました。
  • MySQL では使えないので注意が必要です。

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?