Ecto Assoc with a Composite Foreign Key

ecto

#1

I have a schema with a composite foreign key which looks like this,

has_many :name_a, AllIAsk.Model, references: :a, foreign_key: :a
has_many :name_b, AllIAsk.Model, references: :b, foreign_key: :b:

with a normal foreign key, I could use Ecto.assoc, like this,

model |> ( Ecto.assoc :name_normal_fk ) |> AllIAsk.Repo.one

What’s the best way to do this with a composite foreign key though?


#2

Hoping @michalmuskala can take a look, perhaps I am missing something simple, or not describing this problem well enough…


#3

Right now ecto does not support compound foreign keys when working with associations. This is something that needs to be done manually.


#4

Ah, OK, good to know!


#5

This is my stab. If I can figure out how to get the fields / keys for each assoc it would be a bit better…

 defp composite_fk_assoc(db_struct, assoc_names, keys), do:
    db_struct.__struct__
    |> fn m ->
      assoc_names
      |> (Enum.reduce m,
                      fn(c, a) ->
                        a
                        |> (join :inner, [s], p in (assoc s, ^c))
                      end
        )
      end.()
    |> fn m ->
      keys
      |> (Enum.reduce m,
                     fn(c, a) ->
                       a
                       |> (where [s], ^(map_take_to_list db_struct, c) )
                     end
        )
      end.()
    |> (select [s, p], p)

  defp map_take_to_list(m, k), do:
    m
    |> (Map.take [k])
    |> Map.to_list

#6

Right now ecto does not support compound foreign keys when working with associations.

Is this still the case as of Ecto 3.0.4 ?