Skip to content

Commit ba84b33

Browse files
committed
fix: improve product mapping filteringfix: improve
1 parent 4ccadb3 commit ba84b33

5 files changed

Lines changed: 78 additions & 8 deletions

File tree

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# frozen_string_literal: true
2+
3+
module Sources
4+
class IntegrationMappingsByMappable < GraphQL::Dataloader::Source
5+
def initialize(integration_id = nil)
6+
@integration_id = integration_id
7+
end
8+
9+
def fetch(mappables)
10+
mappings = IntegrationMappings::BaseMapping.where(mappable: mappables)
11+
mappings = mappings.where(integration_id: @integration_id) if @integration_id
12+
mappings_by_mappable = mappings.group_by { [it.mappable_type, it.mappable_id] }
13+
14+
mappables.map do |mappable|
15+
mappings_by_mappable.fetch([mappable.class.polymorphic_name, mappable.id], [])
16+
end
17+
end
18+
end
19+
end

app/graphql/types/products/object.rb

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,7 @@ def filters_count
3838
end
3939

4040
def integration_mappings(integration_id: nil)
41-
mappings = dataloader.with(Sources::ActiveRecordAssociation, :integration_mappings).load(object)
42-
return mappings unless integration_id
43-
44-
mappings.select { |mapping| mapping.integration_id == integration_id }
41+
dataloader.with(Sources::IntegrationMappingsByMappable, integration_id).load(object)
4542
end
4643
end
4744
end

spec/graphql/resolvers/products_resolver_spec.rb

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,20 +46,26 @@
4646

4747
context "with integration mappings" do
4848
let(:integration) { create(:anrok_integration, organization:) }
49+
let(:other_integration) { create(:xero_integration, organization:) }
4950
let!(:usage_mapping) { create(:anrok_mapping, integration:, organization:, mappable: usage_item) }
5051
let!(:fixed_mapping) { create(:anrok_mapping, integration:, organization:, mappable: fixed_item) }
52+
let(:variables) { {integrationId: integration.id} }
5153

5254
let(:query) do
5355
<<~GQL
54-
query {
56+
query($integrationId: ID) {
5557
products(limit: 5) {
56-
collection { id integrationMappings { id } }
58+
collection { id integrationMappings(integrationId: $integrationId) { id } }
5759
}
5860
}
5961
GQL
6062
end
6163

62-
it "loads mappings for all Products in one query" do
64+
before do
65+
create(:xero_mapping, integration: other_integration, organization:, mappable: usage_item)
66+
end
67+
68+
it "loads filtered mappings for all Products in one query" do
6369
query_count = 0
6470
counter = lambda do |_name, _start, _finish, _id, payload|
6571
query_count += 1 if payload[:sql]&.include?('FROM "integration_mappings"')
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# frozen_string_literal: true
2+
3+
require "rails_helper"
4+
5+
RSpec.describe Sources::IntegrationMappingsByMappable do
6+
subject(:source) { described_class.new(integration_id) }
7+
8+
let(:organization) { create(:organization) }
9+
let(:integration) { create(:anrok_integration, organization:) }
10+
let(:other_integration) { create(:xero_integration, organization:) }
11+
let(:integration_id) { integration.id }
12+
let(:product) { create(:product, organization:) }
13+
let(:other_product) { create(:product, organization:) }
14+
let!(:mapping) { create(:anrok_mapping, integration:, organization:, mappable: product) }
15+
let!(:other_mapping) { create(:anrok_mapping, integration:, organization:, mappable: other_product) }
16+
let!(:mapping_for_other_integration) do
17+
create(:xero_mapping, integration: other_integration, organization:, mappable: product)
18+
end
19+
20+
describe "#fetch" do
21+
it "returns mappings for the requested integration grouped by mappable" do
22+
expect(source.fetch([product, other_product])).to eq([[mapping], [other_mapping]])
23+
end
24+
25+
context "without an integration ID" do
26+
let(:integration_id) { nil }
27+
28+
it "returns all mappings grouped by mappable" do
29+
result = source.fetch([product, other_product])
30+
31+
expect(result.first).to match_array([mapping, mapping_for_other_integration])
32+
expect(result.second).to eq([other_mapping])
33+
end
34+
end
35+
end
36+
end

spec/services/integrations/aggregator/base_payload_spec.rb

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
let(:integration) { create(:anrok_integration, organization:) }
1111
let(:product) { create(:product, organization:) }
1212

13-
describe "Product mapping fallback" do
13+
describe "Product mapping lookup" do
1414
let!(:fallback_mapping) do
1515
create(
1616
:anrok_collection_mapping,
@@ -25,5 +25,17 @@
2525

2626
expect(mapping).to eq(fallback_mapping)
2727
end
28+
29+
context "when the Product has a mapping" do
30+
let!(:product_mapping) do
31+
create(:anrok_mapping, integration:, organization:, mappable: product)
32+
end
33+
34+
it "returns the Product mapping" do
35+
mapping = payload.send(:lookup_mapping, "Product", product.id)
36+
37+
expect(mapping).to eq(product_mapping)
38+
end
39+
end
2840
end
2941
end

0 commit comments

Comments
 (0)