Skip to content

Instantly share code, notes, and snippets.

@iiwo
Last active April 11, 2022 15:53
Show Gist options
  • Save iiwo/e402796b13224e9f1408970dc0ff1263 to your computer and use it in GitHub Desktop.
Save iiwo/e402796b13224e9f1408970dc0ff1263 to your computer and use it in GitHub Desktop.
has_one_duplicate.rb
# frozen_string_literal: true
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
gem "activerecord", "6.1"
gem "sqlite3"
end
require "active_record"
require "minitest/autorun"
require "logger"
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Schema.define do
create_table :suppliers do |t|
t.timestamps
end
create_table :accounts do |t|
t.belongs_to :supplier # no unique index allows for duplicates to be created!
# t.belongs_to :supplier, index: { unique: true }, foreign_key: true # prevents duplicates
t.timestamps
end
end
class Supplier <ActiveRecord::Base
# we want a 1<->1 association - so that supplier always has one account
has_one :account
has_one :account_with_forced_order_asc, -> { order('id asc') }, foreign_key: :supplier_id, class_name: 'Account'
has_one :account_with_forced_order_desc, -> { order('id desc') }, foreign_key: :supplier_id, class_name: 'Account'
end
class Account <ActiveRecord::Base
belongs_to :supplier
end
class HasOneTest < Minitest::Test
def setup
Account.destroy_all
Supplier.destroy_all
end
def test_has_one_using_association_method
supplier = Supplier.create!
supplier.create_account!
supplier.create_account!
assert_equal 1, Account.where(supplier: supplier).count # will succeed
# assert_equal 1, Account.count # (but leave orphaned record if no dependent action bahavior defined - separate issue)
end
def test_has_one_duplicate
supplier = Supplier.create!
# we are creating 2 accounts for the same supplier (!) although we expect only one
Account.create!(supplier: supplier)
Account.create!(supplier: supplier)
assert_equal 1, Account.where(supplier: supplier).count # will fail - we have a duplicate!
end
def test_has_one_duplicate_unordered
supplier = Supplier.create!
# we are creating 2 accounts for the same supplier (!) although we expect only one
account = Account.create!(supplier: supplier)
Account.create!(supplier: supplier) # duplicate
assert_equal true, supplier.account == account # flaky - will randomly fail depending on the DB records order
end
def test_has_one_duplicate_order_asc
supplier = Supplier.create!
# we are creating 2 accounts for the same supplier (!) although we expect only one
account = Account.create!(supplier: supplier)
Account.create!(supplier: supplier) # duplicate
assert_equal true, supplier.account_with_forced_order_asc == account # will fail
end
def test_has_one_duplicate_order_desc
supplier = Supplier.create!
# we are creating 2 accounts for the same supplier (!) although we expect only one
account = Account.create!(supplier: supplier)
Account.create!(supplier: supplier) # duplicate
assert_equal true, supplier.account_with_forced_order_desc == account # will fail
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment