環境
- Rails 7.0.0
- Ruby 2.7.5
- MySQL 5.7
前提
- user.rb
class User < ApplicationRecord
has_one :item, dependent: :destroy
end
- item.rb
class Item < ApplicationRecord
belongs_to :user
end
解説
ActiveRecordでhas_one関連付けを利用すると、以下のメソッドが追加される。
build_association(attributes = {})
このメソッドはオブジェクトを作成するだけでレコードを保存・更新・削除しないように見えるが、特定の状況ではレコードが削除される。
準備
userとそれに紐づくitemを作成する。
$ irb(main):001:0> user = User.create!
TRANSACTION (0.3ms) BEGIN
User Create (0.7ms) INSERT INTO `users` (`name`, `created_at`, `updated_at`) VALUES (NULL, '2021-12-22 13:15:26.923535', '2021-12-22 13:15:26.923535')
TRANSACTION (1.6ms) COMMIT
=> #<User:0x00005555bc407cb8 id: 5, name: nil, created_at: Wed, 22 Dec 2021 13:15:26.923535000 UTC +00:00, updated_at: Wed, 22 Dec 2021 13:15:26.923535000 UTC +00:00>
$ irb(main):002:0> user.create_item
TRANSACTION (0.7ms) BEGIN
Item Create (0.8ms) INSERT INTO `items` (`user_id`, `name`, `created_at`, `updated_at`) VALUES (5, NULL, '2021-12-22 13:15:53.782148', '2021-12-22 13:15:53.782148')
TRANSACTION (1.6ms) COMMIT
Item Load (1.2ms) SELECT `items`.* FROM `items` WHERE `items`.`user_id` = 5 LIMIT 1
=> #<Item:0x00007f857080e768 id: 12, user_id: 5, name: nil, created_at: Wed, 22 Dec 2021 13:15:53.782148000 UTC +00:00, updated_at: Wed, 22 Dec 2021 13:15:53.782148000 UTC +00:00>
実際の動作
userがitemを持っている状態で build_item
メソッドを実行すると、古いレコードが削除される。
irb(main):003:0> user.build_item
TRANSACTION (0.7ms) BEGIN
Item Destroy (1.1ms) DELETE FROM `items` WHERE `items`.`id` = 12
TRANSACTION (2.5ms) COMMIT
=> #<Item:0x00007f857045c6d8 id: nil, user_id: 5, name: nil, created_at: nil, updated_at: nil>