rom-sql icon indicating copy to clipboard operation
rom-sql copied to clipboard

ManyToOne associations not being loaded when foreign key is an alias

Open waiting-for-dev opened this issue 6 years ago • 3 comments

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

Original source in the discussion forum

waiting-for-dev avatar Dec 31 '18 08:12 waiting-for-dev

I can't reproduce this anymore using master branches.

solnic avatar Jul 26 '19 09:07 solnic

Quick update: I can reproduce it when it's:

attribute :bad_name_id, Types::Integer, alias: :user_id

solnic avatar Jul 26 '19 09:07 solnic

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.

solnic avatar Jul 26 '19 10:07 solnic