rails: has_one relation start deleting existing record even when new record failed passing validation

Steps to reproduce

class User
  has_one :totp_setting
end

class TotpSetting
  belongs_to :user
  validates :user_id, presence: true, uniqueness: true
end

# in rails 7.0.4
@user.create_totp_setting! # => first record
@user.create_totp_setting! # => uniqueness error

# in rails 7.0.5
@user.create_totp_setting! # => first record
@user.create_totp_setting! # => delete first record and succeeds

Expected behavior

@user.create_totp_setting! # => first record
@user.create_totp_setting! # => uniqueness error

Actual behavior

@user.create_totp_setting! # => first record
@user.create_totp_setting! # => delete first record and succeeds

System configuration

Rails version: 7.0.5

Ruby version: 3.1.4

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 4
  • Comments: 23 (14 by maintainers)

Commits related to this issue

Most upvoted comments

No, what we want to do here is

  • prevent createing has_one relation record if it already exists
  • using model validation

This change has huge huge huge impact. Rails team should release more carefully.

I thought this is unexpected breaking change w/o any changelog mention, but if you say it’s bug fix, I can fix our code base for 7.0.5

@adrianna-chang-shopify Thanks for the detailed investigation.

IMO, this bug report concern is about exception handling, not (only) about the number of rows. I think the Rails v7.0.4 behavior is expected at least for the 7-0-stable branch.

This issue is complicated, so I also would like to know the opinion from @byroot.