Skip to content

Commit

Permalink
Merge pull request #3102 from alphagov/reduce-graphql-queries
Browse files Browse the repository at this point in the history
Optimise render-time link expansion for GraphQL (all editions, except ministers index page)
  • Loading branch information
brucebolt authored Jan 30, 2025
2 parents 71f5ced + 0bca135 commit 6eb106f
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 11 deletions.
21 changes: 11 additions & 10 deletions app/graphql/sources/linked_to_editions_source.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,22 @@ def initialize(parent_object:)
# rubocop:enable Lint/MissingSuper

def fetch(link_types)
link_set_links = @object.document.link_set_links
.includes(target_documents: @content_store) # content_store is :live or :draft (a Document has_one Edition by that name)
.where(link_type: link_types)
.where(target_documents: { locale: "en" })
edition_links = @object.links.order(link_type: :asc, position: :asc)

edition_links = @object.links
.includes(target_documents: @content_store) # content_store is :live or :draft (a Document has_one Edition by that name)
.where(link_type: link_types)
.where(target_documents: { locale: "en" })
all_links = if @object.document.link_set
edition_links.or(@object.document.link_set.links)
else
edition_links
end

all_links = link_set_links + edition_links
all_links_for_link_type_and_locale = all_links
.includes(target_documents: @content_store) # content_store is :live or :draft (a Document has_one Edition by that name)
.where(link_type: link_types)
.where(target_documents: { locale: "en" })

link_types_map = link_types.index_with { [] }

all_links.each_with_object(link_types_map) { |link, hash|
all_links_for_link_type_and_locale.each_with_object(link_types_map) { |link, hash|
hash[link.link_type].concat(editions_for_link(link))
}.values
end
Expand Down
5 changes: 5 additions & 0 deletions db/migrate/20250128101515_add_edition_link_index.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddEditionLinkIndex < ActiveRecord::Migration[8.0]
def change
add_index :links, %i[edition_id link_type]
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[8.0].define(version: 2025_01_27_105807) do
ActiveRecord::Schema[8.0].define(version: 2025_01_28_101515) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_catalog.plpgsql"

Expand Down Expand Up @@ -159,6 +159,7 @@
t.datetime "updated_at", precision: nil, null: false
t.integer "position", default: 0, null: false
t.integer "edition_id"
t.index ["edition_id", "link_type"], name: "index_links_on_edition_id_and_link_type"
t.index ["edition_id"], name: "index_links_on_edition_id"
t.index ["link_set_id", "link_type"], name: "index_links_on_link_set_id_and_link_type"
t.index ["link_set_id", "target_content_id"], name: "index_links_on_link_set_id_and_target_content_id"
Expand Down
21 changes: 21 additions & 0 deletions spec/graphql/sources/linked_to_editions_source_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,25 @@
expect(request.load).to eq([target_edition_1, target_edition_3])
end
end

it "returns a mixture of links when both present" do
target_edition_1 = create(:edition)
target_edition_2 = create(:edition)
target_edition_3 = create(:edition)

source_edition = create(:edition,
links_hash: {
"test_link" => [target_edition_1.content_id],
"another_link_type" => [target_edition_2.content_id],
})

link_set = create(:link_set, content_id: source_edition.content_id)
create(:link, link_set: link_set, target_content_id: target_edition_3.content_id, link_type: "test_link")

GraphQL::Dataloader.with_dataloading do |dataloader|
request = dataloader.with(described_class, parent_object: source_edition).request("test_link")

expect(request.load).to eq([target_edition_1, target_edition_3])
end
end
end

0 comments on commit 6eb106f

Please sign in to comment.