LoginSignup
1
0

More than 3 years have passed since last update.

Rails6 のちょい足しな新機能を試す109(while_preventing_writes 編)

Posted at

はじめに

Rails 6 に追加された新機能を試す第109段。 今回は、while_preventing_writes 編です。
Rails 6 では、 while_preventing_writes が追加されました。

multi-db 関連のメソッドで、 while_preventing_writes のブロック内では、 DBへの書き込みができません。
同じDBに対してDBのConnection を別に作成しても書き込みはできないようになっています。

Ruby 2.6.5, Rails 6.0.0 で確認しました。

$ rails --version
Rails 6.0.0

今回は、簡単なスクリプトを作って確認します。

Rails プロジェクトを作成する

$ rails new rails_sandbox
$ cd rails_sandbox

User モデルを作成する

User モデルを作成します。

$ bin/rails g model User name

User モデルを編集する

User モデルのDBの Connection を ActiveRecord::Base.connection とは別になるように変更します。

app/models/user.rb
class User < ApplicationRecord
  connects_to database: { writing: :primary, reading: :primary }
end

動作確認のスクリプトを作成する

ActiveRecord::Base.connectionUser.connection が違うことを確認し、 while_preventing_writes のブロック内では、DBへの書き込みができないことを確認します。

scripts/while_preventing_writes.rb
puts User.count

if ActiveRecord::Base.connection.object_id != User.connection.object_id
  puts 'ActiveRecord::Base.connection != User.connection'
end

# ActiveRecord::Base.connection.while_preventing_writes do # Rails 6.0.0.rc1
ActiveRecord::Base.connection_handler.while_preventing_writes do # Rails 6.0.0
  User.create!(name: 'Taro')
end

puts User.count

マイグレーションを実行する

$ bin/rails db:create db:migrate

スクリプトを実行する

スクリプトを実行します。 Write query attempted while in readonly mode: のメッセージが出力され、書き込みが失敗することがわかります。

$ bin/rails runner scripts/while_preventing_writes.rb
Running via Spring preloader in process 81
0
ActiveRecord::Base.connection != User.connection
Traceback (most recent call last):
...
/usr/local/bundle/gems/activerecord-6.0.0/lib/active_record/connection_adapters/postgresql_adapter.rb:643:in `execute_and_clear': Write query attempted while in readonly mode: INSERT INTO "users" ("name", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" (ActiveRecord::ReadOnlyError)

ちなみに

Rails 6.0.0rc1 では、エラーにならず、保存できてしまいます。(6.0.0rc1 では、メソッドの定義場所が異なるため、 ActiveRecord::Base.connection.while_preventing_writes とする必要があります。)

試したソース

試したソースは以下にあります。
https://github.com/suketa/rails_sandbox/tree/try109_while_preventing_writes

参考情報

1
0
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
0