rom-sql
rom-sql copied to clipboard
ManyToOne associations not being loaded when foreign key is an alias
Describe the bug
If you have a belongs_to
association where the foreign key attribute has been aliased, the association is always loaded as nil
even when the foreign key attribute is populated.
To Reproduce
git clone https://github.com/waiting-for-dev/rom_bug_aliased_fk
cd rom_bug_aliased_fk
bundle
ruby reproduce.rb
or
require "rom"
module Types
include Dry::Types.module
end
rom = ROM.container(:sql, 'sqlite::memory') do |conf|
conf.default.create_table(:users) do
primary_key :id
column :name, String, null: false
end
conf.default.create_table(:tasks) do
primary_key :id
column :name, String, null: false
foreign_key :bad_name_id, :users, null: false
end
conf.relation(:users) do
schema(infer: true)
end
conf.relation(:tasks_without_alias) do
schema(:tasks, infer: true, as: :tasks_without_alias) do
associations do
belongs_to(:user)
end
end
end
conf.relation(:tasks_with_alias) do
schema(:tasks, infer: true, as: :tasks_with_alias) do
attribute :bad_name_id, Types::Integer.meta(alias: :user_id)
associations do
belongs_to(:user)
end
end
end
end
joe = rom.relations[:users].command(:create).(name: "Joe Doe")
rom.relations[:tasks_without_alias].command(:create).(name: "Be happy", bad_name_id: joe[:id])
puts "Output combining from relation without FK aliased"
puts rom.relations[:tasks_without_alias].combine(:users).to_a
# => {:id=>1, :name=>"Be happy", :bad_name_id=>1, :user=>{:id=>1, :name=>"Joe Doe"}}
puts "====================="
puts "Output combining from relation with FK aliased"
puts rom.relations[:tasks_with_alias].combine(:users).to_a
# => {:user_id=>1, :id=>1, :name=>"Be happy", :user=>nil}
Expected behavior
I would expected that foreign key inference is not affected by aliasing the attribute at the application level.
Your environment
- Affects my production application: YES
- Ruby version: 2.5.3p105
- OS: NixOS
Resources
I can't reproduce this anymore using master branches.
Quick update: I can reproduce it when it's:
attribute :bad_name_id, Types::Integer, alias: :user_id
I moved this to rom-sql since it's sql-specific. We need to set combine_keys
option if there are fk aliases. ie if you do this:
belongs_to(:user, combine_keys: { user_id: :id })
...then it's gonna work.