2015-10-02 20 views
27

Mam model Użytkownicy i model Czaty. Intuicyjnie wiele osób należy do tej samej grupy czatu w każdej chwili i każda osoba może mieć wiele grup czatu. W związku z tym grupa czatu musi należeć do wielu adresów user_id.Wiele do wielu relacji w Ecto

Moje schematu do grupy czatu, a użytkownicy są:

schema "chatGroups" do 
    field :name, :string 
    has_many :messages, Message 
    belongs_to :user, User 

    timestamps 
end 

schema "users" do 
    field :name, :string 
    has_many :chatGroups, ChatGroup 

    timestamps 
end 

Wszelkie sugestie, jak sobie z tym poradzić?

Odpowiedz

34

Ecto ma wsparcie dla has_many/3 poprzez relacje. Obejmuje to tworzenie tabeli pośredniej między Twoimi grupami czatu a Twoimi użytkownikami.

Można to zrobić za pomocą następującego schematu:

chat_group.ex:

schema "chat_groups" do 
    has_many :chat_group_users, MyApp.ChatGroupUser 
    has_many :users, through: [:chat_group_users, :user] 
end 

chat_group_user.ex:

schema "chat_group_users" do 
    belongs_to :chat_group, MyApp.ChatGroup 
    belongs_to :user, MyApp.User 
end 

Można również zrobić stowarzyszenie w drugą stronę:

użytkownik.ex:

schema "users" do 
    has_many :chat_group_users, MyApp.ChatGroupUsers 
    has_many :chats, through: [:chat_group_users, :chat] 
end 

To pozwala robić takie rzeczy jak:

Repo.get(Chat, 1) |> Repo.preload(:users) 

ten pobierze użytkowników dla danego modelu czatu i wypełnić klucz :user z wartością.

+2

Darn. Miałem nadzieję na rozwiązanie, które nie wymaga tworzenia tabeli złączeń. No cóż. Dziękuję za wyjaśnienie! Zbadam to w ten weekend i zaakceptuję, gdy już to zrobię. –

+1

Działa to poza składnią dla mnie: 'through: [: chat_group_users,: chat]' (zauważ dwukropek przed pierwszym parametrem i przecinek po nim,) –

+0

Chowza, fajnie jest zrobić to jawnie w ten sposób możesz ustawić swoją tablicę sprzężeń, aby miała odwołanie do klucza obcego za pomocą: delete_all, aby tablica dołączeń oczyszczała się po usunięciu powiązanych rekordów. – brightball