2017-12-28 36 views
0

내 블로그 앱에는 Comment이 많은 Post 모델이 있습니다.고급 : assoc with elixir 압생트

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 

나는 관련된 absinthe 개체도 가지고 있습니다.

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 

쿼리가 예상대로 작동합니다.

지금 소프트 픽스를 수행 할 수 있도록 필드를 Comments 스키마에 추가하고 싶습니다. 나는 단지 active == true 인 주석을 선택하고 activefalse으로 설정하여 주석을 삭제합니다.

나는 나의 스키마에 필드를 추가 :

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

가 지금은 단지 압생트 :comments 필드가 활성 주석을 반환합니다. 나는 이것을위한 커스텀 리졸버를 가지고있다 ...

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 

나는 이것이 N + 1 문제에 부딪 힐 것이라 생각한다. 이 일을 더 우아한 방법이 있습니까?

답변

2

여기서 Batch Resolver을 사용해야합니다. documentation은 모든 것을 자세히 설명합니다. 검색어는 다음과 같아야합니다.

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)}