2017-12-28 13 views
0

私のブログのアプリには、CommentがたくさんあるPostモデルがあります。もっと進んだ:アソシエントとエリクシル・アンプンテフ

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 

私は関連するabsentオブジェクトも持っています。

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 

クエリは期待通りに機能します。

スキーマにブール値activeフィールドを追加して、ソフト削除を実行できるようにします。コメントを選択するのは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)} 
関連する問題