Ecto - 自我参考,has_many通过

时间:2017-04-10 13:57:11

标签: elixir phoenix-framework ecto

我有以下用户模块:

  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}无法找到用户2,但为什么不能找到friends?关系有问题吗?

1 个答案:

答案 0 :(得分:2)

  

我理解为什么用户2找不到friends,但为什么不能找到友谊?关系有问题吗?

因为friendships仅涉及user的{​​{1}}字段。您的查询仅搜索Friendship,但由于创建的友谊包含friendships.user_id = 2user_id = 1,因此不返回任何内容。

您可以创建另一种关系,例如friend_id = 2,这将返回用户为reverse_friendships的友情,而不是friend

user

现在has_many :reverse_friendships, Friendship, foreign_key: :friend_id 没有user1reverse_friendshipsuser2 reverse_friendships