If you make a belongs_to association inside trait, it will be created 2 times. This causes an error if there is a uniqueness check.
I have written a test for an example.
On version 0.10.2 it works correct.
To Reproduce
# frozen_string_literal: true
RSpec.describe ROM::Factory do
include_context "database"
subject(:factories) do
ROM::Factory.configure do |config|
config.rom = rom
end
end
before do
conn.create_table?(:book_types) do
primary_key :id
column :type, String, null: false
index :type, unique: true
end
conn.create_table?(:books) do
primary_key :id
foreign_key :book_type_id, :book_types, index: true
end
conf.relation(:book_types) do
schema(infer: true) do
associations do
has_many :books
end
end
end
conf.relation(:books) do
schema(infer: true) do
associations do
belongs_to :book_type
end
end
end
rom.gateways[:default].use_logger(Logger.new($stdout))
end
context "trait with associations" do
it "creates book type only once" do
factories.define(:book) do |f|
f.trait :with_type do |t|
t.association(:book_type)
end
end
factories.define(:book_type) do |f|
f.type { "NOT_UNIQUE" }
end
factories[:book, :with_type]
expect(rom.relations[:book_types].count).to eq(1)
end
end
after do
conn.drop_table?(:books)
conn.drop_table?(:book_types)
end
end
And the error
I, [2024-07-22T16:45:11.954139 #19499] INFO -- : (0.002133s) INSERT INTO "book_types" ("type") VALUES ('NOT_UNIQUE') RETURNING "book_types"."id", "book_types"."type"
E, [2024-07-22T16:45:11.955342 #19499] ERROR -- : PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "book_types_type_index"
DETAILS: Key (type)=(NOT_UNIQUE) already exists.: INSERT INTO "book_types" ("type") VALUES ('NOT_UNIQUE') RETURNING "book_types"."id", "book_types"."type"
I, [2024-07-22T16:45:11.964446 #19499] INFO -- : (0.008830s) DROP TABLE IF EXISTS "books"
I, [2024-07-22T16:45:11.970889 #19499] INFO -- : (0.006384s) DROP TABLE IF EXISTS "book_types"
F
Failures:
1) ROM::Factory trait with associations creates book type only once
Failure/Error:
result = relation
.with(auto_struct: !tuple_evaluator.has_associations?)
.command(:create)
.call(attrs)
ROM::SQL::UniqueConstraintError:
PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "book_types_type_index"
DETAILS: Key (type)=(NOT_UNIQUE) already exists.
# ./lib/rom/factory/builder/persistable.rb:48:in `persist'
# ./lib/rom/factory/builder/persistable.rb:28:in `create'
# ./lib/rom/factory/attributes/association.rb:82:in `call'
# ./lib/rom/factory/tuple_evaluator.rb:186:in `block in evaluate_associations'
# ./lib/rom/factory/attribute_registry.rb:22:in `each'
# ./lib/rom/factory/attribute_registry.rb:22:in `each'
# ./lib/rom/factory/tuple_evaluator.rb:178:in `each_with_object'
# ./lib/rom/factory/tuple_evaluator.rb:178:in `evaluate_associations'
# ./lib/rom/factory/tuple_evaluator.rb:149:in `evaluate'
# ./lib/rom/factory/tuple_evaluator.rb:59:in `defaults'
# ./lib/rom/factory/tuple_evaluator.rb:173:in `evaluate_traits'
# ./lib/rom/factory/tuple_evaluator.rb:150:in `evaluate'
# ./lib/rom/factory/tuple_evaluator.rb:59:in `defaults'
# ./lib/rom/factory/builder.rb:37:in `tuple'
# ./lib/rom/factory/builder/persistable.rb:27:in `create'
# ./lib/rom/factory/factories.rb:171:in `[]'
# ./spec/integration/rom/association_trait_spec.rb:56:in `block (3 levels) in <top (required)>'
# ------------------
# --- Caused by: ---
# PG::UniqueViolation:
# ERROR: duplicate key value violates unique constraint "book_types_type_index"
# DETAILS: Key (type)=(NOT_UNIQUE) already exists.
# ./lib/rom/factory/builder/persistable.rb:48:in `persist'
Expected behavior
Associations in traits should be created only 1 time.
Describe the bug
If you make a belongs_to association inside trait, it will be created 2 times. This causes an error if there is a uniqueness check. I have written a test for an example.
On version 0.10.2 it works correct.
To Reproduce
And the error
Expected behavior
Associations in traits should be created only 1 time.
My environment