Ecto - 自参考,has_many 通过

Ecto - Self reference, has_many through

我有以下用户模块:

  schema "accounts_users" do
    has_many :friendships, Friendship
    has_many :friends, through: [:friendships, :friend]

    timestamps()
  end

友谊模块:

  schema "accounts_friendships" do
    belongs_to :user, User
    belongs_to :friend, User

    timestamps()
  end

和友谊迁移:

  def change do
    create table(:accounts_friendships) do
      add :user_id, references(:accounts_users, on_delete: :nothing)
      add :friend_id, references(:accounts_users, on_delete: :nothing)

      timestamps()
    end

    create index(:accounts_friendships, [:user_id])
    create index(:accounts_friendships, [:friend_id])
  end

我可以像这样在用户 1 和用户 2 之间建立新的友谊:

 %Friendship{user_id: 1, friend_id: 2} |> Repo.insert()

用户 1 的行为符合预期:

Repo.all(Ecto.assoc(user1, :friendships)) # => [%Friendship{...}]
Repo.all(Ecto.assoc(user1, :friends)) # => [%User{...}]

但不适用于用户 2 :

Repo.all(Ecto.assoc(user2, :friendships)) # => []
Repo.all(Ecto.assoc(user2, :friends)) # => []

我明白为什么找不到用户 2 的 friends,但为什么找不到 friendships?关系有问题吗?

I understand why friends can't be found for user 2, but why not the friendships ? Is something wrong with the relation ?

因为friendships只关心Friendshipuser字段。您的查询仅搜索 friendships.user_id = 2,它不会 return 任何内容,因为创建的 Friendship 有 user_id = 1friend_id = 2.

您可以创建另一个关系,比如 reverse_friendships,这将 return 用户是 friend 而不是 user:[=27= 的友谊]

has_many :reverse_friendships, Friendship, foreign_key: :friend_id

现在 user1 将没有 reverse_friendshipsuser2 将有 reverse_friendshipsuser1