2017-12-28 15 views
0

Meine Blog-App hat eine Post Modell, das viele Comment s hat.Fortgeschrittener: assoziieren mit Elixier Absinth

schema "post" do 
    field :title, :string 
    field :content, :string 

    belongs_to :owner, MyApp.Accounts.User, foreign_key: :owner_id 

    has_many :comments, MyApp.Content.Comment, foreign_key: :post_id 

    timestamps() 
end 

Ich habe auch ein Absinth-Objekt zugeordnet.

object :post do 
    field :id, :integer 
    field :title, :string 
    field :content, :string 
    field :owner, :user, resolve: assoc(:owner) 
    field :comments, list_of(:comment), resolve: assoc(:comments) 
end 

Abfragen funktionieren wie erwartet.

Jetzt möchte ich ein boolesches active Feld zu dem Comments Schema hinzufügen, damit ich weiche Löschungen durchführen kann; Ich wähle nur Kommentare aus, wo active == true, und ich werde Kommentare löschen, indem Sie active auf false setzen.

füge ich das Feld in mein Schema:

field :active, :boolean, default: true, null: false 

Jetzt habe ich nur das Absinth :comments Feld aktiv Kommentare zurückkehren möchten. Ich habe einen benutzerdefinierten Resolver für diese ...

field :comments, list_of(:comment), resolve: fn (query,_,resolution) -> 
    query = 
    from c in MyApp.Content.Comment, 
     where: c.post_id == ^query.id, 
     where: c.active == true, 
     select: c 

    {:ok, MyApp.Repo.all(query)} 
end 

Ich mache mir Sorgen, dies obwohl in ein N + 1 Problem laufen wird. Gibt es einen eleganteren Weg, dies zu tun?

Antwort

2

Sie müssen hier eine Batch Resolver verwenden. Die documentation erklärt alles im Detail. Ihre Abfrage sollte wie folgt aussehen:

query = 
    from c in MyApp.Content.Comment, 
    where: c.post_id in ^post_ids, 
    where: c.active == true, 
    select: c 

{:ok, query |> MyApp.Repo.all() |> Enum.group_by(& &1.post_id)} 
Verwandte Themen