2017-04-10 3 views
1

habe ich folgendes Platzmodul:Ecto - Selbstreferenz, has_many durch

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

    timestamps() 
    end 

Die Friendship-Modul:

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

    timestamps() 
    end 

Und die Freundschaft Migration:

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 

ich erstellen kann eine neue Freundschaft zwischen Benutzer 1 und Benutzer 2 wie folgt:

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

Das Verhalten funktioniert wie erwartet für Benutzer 1:

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

Aber nicht für Benutzer 2:

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

Ich verstehe, warum friends nicht für Benutzer 2 zu finden, aber warum nicht die friendships? Stimmt etwas nicht mit der Beziehung?

Antwort

2

Ich verstehe, warum friends nicht für Benutzer 2 gefunden werden kann, aber warum nicht die Freundschaften? Stimmt etwas nicht mit der Beziehung?

Da friendships ist nur mit user Bereich der Friendship betroffen. Ihre Abfrage sucht nur nach friendships.user_id = 2, die nichts zurückgibt, da die erstellte Freundschaft user_id = 1 und friend_id = 2 hatte.

Sie eine andere Beziehung erstellen können, sagen reverse_friendships, die die Freundschaften zurückkehren, wo der Benutzer die friend ist, nicht die user:

has_many :reverse_friendships, Friendship, foreign_key: :friend_id 

Jetzt wird user1 haben keine reverse_friendships aber user2 wird eine reverse_friendships mit user1 .