Многие ко многим на одном столе в Фениксе

Использование Ecto v2.2.6, Phoenix 1.3

У меня есть таблица людей (которые связаны друг с другом) и еще одна таблица отношений для этих людей. В таблице отношений идентификатор родителя указан в одном столбце, а идентификатор дочернего элемента — в другом.

mix phx.gen.json Accounts Person persons name:string age:integer
mix phx.gen.json Accounts Relationship relationships parent_id:references:persons child_id:references:persons

Теперь я собираюсь добавить отношения own_to в схему отношений (которая в настоящее время выглядит так)

  schema "relationships" do
    field :parent_id, :id
    field :child_id, :id
    timestamps()
  end

Но без возможности явно указать идентификатор это выглядело бы так (что, похоже, не работает)

  schema "relationships" do
    belongs_to :person UserRelations.Accounts.Person 
    belongs_to :person UserRelations.Accounts.Person 
    timestamps()
  end

Как я могу написать схему отношений, чтобы зафиксировать эти belongs_to отношения?

Редактировать

Я настроил схему следующим образом, согласно предложению:

  schema "relationships" do
    belongs_to :parent UserRelations.Accounts.Person 
    belongs_to :child UserRelations.Accounts.Person 
    timestamps()
  end

Я попытался сделать что-то подобное и со схемой Person:

  schema "persons" do
    field :age, :integer
    field :name, :string
    many_to_many :parent_of, UserRelations.Accounts.Person, join_through: "relationships"
    many_to_many :child_of, UserRelations.Accounts.Person, join_through: "relationships"
    timestamps()
  end

Однако, когда я пытаюсь получить доступ к этим отношениям (я делаю это через схему absinthe/graphql), я вижу, что она где-то ищет person_id:

[error] Task #PID<0.400.0> started from #PID<0.395.0> terminating
** (Postgrex.Error) ERROR 42703 (undefined_column): column f2.person_id does not exist

person Mark Karavan    schedule 08.10.2017    source источник
comment
Просто переименовать второй в belongs_to :child?   -  person Dogbert    schedule 08.10.2017
comment
@Dogbert Попытался реализовать это. См. редактирование выше.   -  person Mark Karavan    schedule 08.10.2017
comment
Я думаю, вам нужно добавить join_keys: [parent_id: :id, child_id: id] к первому many_to_many и обратное ([child_id: :id, parent_id: :id]) ко второму.   -  person Dogbert    schedule 08.10.2017
comment
@Dogbert Perfect, это сработало именно так, как заявлено. Если вы превратите эти два комментария в ответ, я отмечу их как правильные.   -  person Mark Karavan    schedule 08.10.2017


Ответы (1)


  1. Имена двух отношений принадлежности_к должны быть разными. Например:

    belongs_to :child, UserRelations.Accounts.Person 
    belongs_to :parent, UserRelations.Accounts.Person 
    

    С этими именами Ecto правильно определит внешний ключ: child_id и parent_id.

  2. Для many_to_many вам необходимо указать join_keys для обоих, поскольку Ecto не может сделать вывод об этом из имени отношения и модуля схемы.

    Для первого нужно добавить:

    , join_keys: [parent_id: :id, child_id: :id]
    

    И для второго:

    , join_keys: [child_id: :id, parent_id: :id]
    
person Dogbert    schedule 09.10.2017