Combines with an association with composite keys

Hi,

We have the following schema:

class Numbers < ROM::Relation[:sql]
  schema(:numbers, infer: true) do
    attribute :company_id, Types::Int
    attribute :region_id, Types::Int

    associations do
      has_one :identities, view: :for_numbers, override: true
    end
  end
end

class Identities < ROM::Relation[:sql]
  schema(:identities, infer: true) do
    attribute :company_id, Types::Int
    attribute :region_id, Types::Int
  end

  def for_numbers(_assoc, _identities)
    join(:numbers, { region_id: :region_id, company_id: :company_id })
  end
end

We want to be able to combine the identities into numbers by associating them. They’re only “loosely” related, not strictly related — a number will be associated with an identity if they both have the same region_id and company_id.

For whatever reason though, when I use combine, I always get an empty identity value in our struct:

numbers.combine(:identity).by_pk(1).one # => { id: 1, company_id: 42, region_id: 28, identity: nil }

I’m not sure why this is happening — if I run that join normally on identities, I’ll get the correct entities.

@ethnt is this a legacy schema or is it something that you put together and can still change it? I’m asking because using composite keys is not recommended due to all the potential issues you may face.

Anyhow, your attribute definitions are missing FK info, you need to do attribute :company_id, Types.ForeignKey(:companies) otherwise rom will not know that it’s a foreign key. Secondly, you need to provide combine keys in the association definition, so has_one :identities, ..., combine_keys: %i[region_id company_id].

Please try this and let me know if this worked.