From 0b2eff5d93c16b272b9b6b89b1ee100b5ee846de Mon Sep 17 00:00:00 2001 From: Wojciech Maciejak Date: Fri, 20 Oct 2017 14:37:41 +0200 Subject: [PATCH] [temp][fix] Naive improvement for fetching many-to-one relations https://github.com/exAspArk/batch-loader/issues/5 --- README.md | 2 +- app/graphql/types/post_type.rb | 7 +++---- app/graphql/types/user_type.rb | 16 +++++++--------- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index f8126dd..07dc148 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ This is a sample app which shows how Rails 5, ROM 4.0, GraphQL and Clean Archite - [x] modularization of fields in QueryType [app/graphql/query_type.rb](https://github.com/wmaciejak/rails_rom_graphql_clean_architecture_boilerplate/blob/master/app/graphql/query_type.rb#L6) - [x] Implementation of Clean Architecture - [x] Separation of seeds by the environment [db/seeds.rb](https://github.com/wmaciejak/rails_rom_graphql_clean_architecture_boilerplate/blob/master/db/seeds.rb) +- [x] Loading relations one-to-many without N+1, fixed by naive implementation - [BatchLoader issue#5](https://github.com/exAspArk/batch-loader/issues/5) ## What's to be done @@ -32,7 +33,6 @@ This is a sample app which shows how Rails 5, ROM 4.0, GraphQL and Clean Archite ## Known issues -- [ ] [BatchLoader issue#5](https://github.com/exAspArk/batch-loader/issues/5) - Partly fixed by custom solution but it's still `in progress` - [ ] camelCase in queries(thx [RadoMark](https://github.com/RadoMark/)) ## Links diff --git a/app/graphql/types/post_type.rb b/app/graphql/types/post_type.rb index 6028773..878fc82 100644 --- a/app/graphql/types/post_type.rb +++ b/app/graphql/types/post_type.rb @@ -7,11 +7,10 @@ field :title, !types.String field :created_at, !types.String field :updated_at, !types.String - field :comments, CommentType, resolve: ->(post, _, _) do + field :comments, types[CommentType], resolve: ->(post, _, _) do BatchLoader.for(post.id).batch do |post_ids, loader| - CommentRepo.new(ROM.env).all_for_posts(post_ids).each do |comment| - loader.call(comment.post_id, comment) - end + grouped_hash = CommentRepo.new(ROM.env).all_for_posts(post_ids).group_by(&:post_id) + post_ids.each { |post_id| loader.call(post_id, grouped_hash[post_id]) } end end end diff --git a/app/graphql/types/user_type.rb b/app/graphql/types/user_type.rb index b2e79ee..de99066 100644 --- a/app/graphql/types/user_type.rb +++ b/app/graphql/types/user_type.rb @@ -4,18 +4,16 @@ name "User" field :email, types.String field :username, types.String - field :posts, PostType, resolve: ->(user, _, _) do + field :posts, types[PostType], resolve: ->(user, _, _) do BatchLoader.for(user.id).batch do |user_ids, loader| - PostRepo.new(ROM.env).all_for_user(user_ids).each do |post| - loader.call(post.user_id, post) - end + grouped_hash = PostRepo.new(ROM.env).all_for_user(user_ids).group_by(&:user_id) + user_ids.each { |user_id| loader.call(user_id, grouped_hash[user_id]) } end end - field :comments, CommentType, resolve: ->(user, _, _) do - BatchLoader.for(user.id).batch do |user_ids, loader| - CommentRepo.new(ROM.env).all_for_author(user_ids).each do |comment| - loader.call(comment.author_id, comment) - end + field :comments, types[CommentType], resolve: ->(user, _, _) do + BatchLoader.for(user.id).batch do |author_ids, loader| + grouped_hash = CommentRepo.new(ROM.env).all_for_author(author_ids).group_by(&:author_id) + author_ids.each { |author_id| loader.call(author_id, grouped_hash[author_id]) } end end end