Более продвинутый: ассоциируйся с эликсиром абсента
В моем блоге есть Post
модель, которая имеет много Comment
s.
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
У меня также есть связанный объект абсента.
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
поле к Comments
схема, чтобы я мог выполнить мягкое удаление; Я выберу только комментарии, где active == true
и я буду удалять комментарии, установив active
в false
,
Я добавляю поле в мою схему:
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. Есть ли более элегантный способ сделать это?
1 ответ
Решение
Вам нужно использовать Batch Resolver
Вот. Документация объясняет все подробно. Ваш запрос должен выглядеть следующим образом:
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)}