Torihaji's Growth Diary

Little by little, no hurry.

Rails transactionメソッドの使い分けについて自分なりにまとめてみた。

はじめに

みなさん、こんにちは! torihaziです!

8/1から念願のWeb開発エンジニアライフがスタートしているわけですが

Railsのお仕事をもらってタイトルのことで少し疑問に思ったので

これを機に調べてみました!!

簡単にまとめた程度です。

ではどーぞ!

そもそもtransactionとは

Railsでデータベースを扱う場合、レコード作成や更新等の操作があります

そこでよく出てくるのがトランザクション

一連の操作を単一のものとして扱い、

それらが全部成功したら成功とし、1つでも失敗したら無かったことにする

というあれです。

Railsでtransactionを扱うにはtransactionメソッドというものを使用する必要があります!

railsdoc.com

使い分け

ActiveRecord::Base.transaction の使用

複数のモデルにまたがる操作を行う場合

特定のモデルに関連付けられていない一般的なデータベース操作を行う場合

ActiveRecord::Base.transaction do
  User.create!(name: "Alice")
  Post.create!(title: "Hello", user: User.last)
end

モデルクラスでの transaction の使用:

特定のモデルに関連する操作のみを行う場合 そのモデルに特化したトランザクションロジックがある場合

User.transaction do
  user = User.create!(name: "Bob")
  user.posts.create!(title: "My First Post")
end

モデルインスタンスでの transaction の使用:

特定のレコードに関連する複数の操作を行う場合 インスタンスメソッド内でトランザクションを使用する場合

user = User.find(1)
user.transaction do
  user.update!(name: "Charlie")
  user.posts.create!(title: "New Post")
end

使い分けの基準:

  • 操作の範囲:複数のモデルにまたがる場合は ActiveRecord::Base.transaction を使用
  • コンテキスト:特定のモデルやインスタンスに関連する操作の場合は、そのモデルやインスタンスの transaction を使用
  • コードの場所:モデル内のクラスメソッドではクラスレベルの transaction を、インスタンスメソッドではインスタンスレベルの transaction を使用
  • 読みやすさ:コードの文脈に最も適した方法を選択

だということ。

終わりに

究極、

ActiveRecord::Base.transaction do
~~
end

としておけば、良さげな気はする。

あとは一目でわかるか否かということなのかしら。

また気になった時に調べてみる。