LoginSignup
1
0

More than 1 year has passed since last update.

has_one関連付けのbuild_associationメソッドは暗黙的にレコードを削除する

Posted at

環境

  • 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>
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