Skip to content

Instantly share code, notes, and snippets.

@libkazz
Last active October 6, 2022 02:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save libkazz/891cba589f6f0ffc849fa6baefab8388 to your computer and use it in GitHub Desktop.
Save libkazz/891cba589f6f0ffc849fa6baefab8388 to your computer and use it in GitHub Desktop.
source "https://rubygems.org"
gem "activerecord", '~> 7.0'
gem "sqlite3"
# Usage
# ```
# bundle exec ruby has_one_and_validation.rb
# ```
require 'active_record'
class ActiveRecord::Base
establish_connection adapter: 'sqlite3', database: 'foobar.db'
end
class Foo < ActiveRecord::Base
has_one :bar, dependent: :destroy
end
class Bar < ActiveRecord::Base
belongs_to :foo
end
ActiveRecord::Base.connection.tap do |connection|
connection.create_table :foos, force: true
connection.create_table :bars, force: true do |t|
t.references :foo
end
end
#
# Without validation
#
foo = Foo.create!
bar1 = foo.create_bar
# validation がなければ想定どおりに作られている
bar2 = foo.create_bar
p Bar.all.pluck(:id) #=> [2]
# ただし validation がないので重複するレコードを作成しうる
bar3 = Bar.create(foo: foo)
p Bar.all.pluck(:id) #=> [2, 3]
#
# With validation
#
Foo.delete_all
Bar.delete_all
Bar.class_eval do
validates(:foo, uniqueness: true)
end
foo = Foo.create!
bar1 = foo.create_bar
# validation と has_one が競合して恐ろしいことになる
bar2 = foo.create_bar
p Bar.all.pluck(:id) #=> []
# ただし重複レコードの発生は防ぐことができる
bar1 = foo.create_bar # 消えているので作り直し
bar3 = Bar.create(foo: foo)
p Bar.all.pluck(:id) #=> [5]
@libkazz
Copy link
Author

libkazz commented Oct 6, 2022

create_bar! にすれば、恐ろしいこと は防ぐことができる

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment