diff --git a/packages/forest_admin_agent/lib/forest_admin_agent/builder/agent_factory.rb b/packages/forest_admin_agent/lib/forest_admin_agent/builder/agent_factory.rb index 1983a38ef..e4f7fba41 100644 --- a/packages/forest_admin_agent/lib/forest_admin_agent/builder/agent_factory.rb +++ b/packages/forest_admin_agent/lib/forest_admin_agent/builder/agent_factory.rb @@ -99,6 +99,8 @@ def reload! # Reset route cache before sending schema to ensure routes are recomputed with all customizations ForestAdminAgent::Http::Router.reset_cached_routes! + # The datasource was rebuilt, so the serializer's primary-key cache may be stale + ForestAdminAgent::Serializer::ForestSerializer.reset_cache! @logger.log('Info', 'route cache cleared due to agent reload') send_schema diff --git a/packages/forest_admin_agent/lib/forest_admin_agent/serializer/forest_serializer.rb b/packages/forest_admin_agent/lib/forest_admin_agent/serializer/forest_serializer.rb index 0f2ba7d0d..1da0e4c89 100644 --- a/packages/forest_admin_agent/lib/forest_admin_agent/serializer/forest_serializer.rb +++ b/packages/forest_admin_agent/lib/forest_admin_agent/serializer/forest_serializer.rb @@ -24,11 +24,15 @@ def type @@class_names[class_name] ||= class_name.gsub('::', '__') end + def self.reset_cache! + @@primary_keys = {} + end + def id - forest_collection = ForestAdminAgent::Facades::Container.datasource.get_collection( - @options[:class_name].gsub('::', '__') + @@primary_keys ||= {} + primary_keys = @@primary_keys[type] ||= ForestAdminDatasourceToolkit::Utils::Schema.primary_keys( + ForestAdminAgent::Facades::Container.datasource.get_collection(type) ) - primary_keys = ForestAdminDatasourceToolkit::Utils::Schema.primary_keys(forest_collection) primary_keys.map { |key| @object[key] }.join('|') end diff --git a/packages/forest_admin_agent/spec/lib/forest_admin_agent/builder/agent_factory_spec.rb b/packages/forest_admin_agent/spec/lib/forest_admin_agent/builder/agent_factory_spec.rb index 342e65b3a..fea917258 100644 --- a/packages/forest_admin_agent/spec/lib/forest_admin_agent/builder/agent_factory_spec.rb +++ b/packages/forest_admin_agent/spec/lib/forest_admin_agent/builder/agent_factory_spec.rb @@ -136,6 +136,17 @@ module Builder expect(instance.customizer).to have_received(:reload!) end + it 'resets the serializer primary-key cache' do + instance = described_class.instance + allow(instance).to receive(:send_schema) + allow(instance.customizer).to receive(:reload!) + allow(ForestAdminAgent::Serializer::ForestSerializer).to receive(:reset_cache!) + + instance.reload! + + expect(ForestAdminAgent::Serializer::ForestSerializer).to have_received(:reset_cache!) + end + it 'add datasource to the container' do allow(described_class.instance).to receive(:send_schema) described_class.instance.reload! diff --git a/packages/forest_admin_datasource_toolkit/lib/forest_admin_datasource_toolkit/decorators/collection_decorator.rb b/packages/forest_admin_datasource_toolkit/lib/forest_admin_datasource_toolkit/decorators/collection_decorator.rb index bbc561079..e72573de9 100644 --- a/packages/forest_admin_datasource_toolkit/lib/forest_admin_datasource_toolkit/decorators/collection_decorator.rb +++ b/packages/forest_admin_datasource_toolkit/lib/forest_admin_datasource_toolkit/decorators/collection_decorator.rb @@ -28,7 +28,9 @@ def schema end def name - @child_collection.name + # `@name` is taken by the base Collection (set via the mis-ordered `super` in initialize), + # so memoize under a dedicated ivar. + @memoized_name ||= @child_collection.name # rubocop:disable Naming/MemoizedInstanceVariableName end def execute(caller, name, data, filter = nil) diff --git a/packages/forest_admin_datasource_toolkit/lib/forest_admin_datasource_toolkit/decorators/datasource_decorator.rb b/packages/forest_admin_datasource_toolkit/lib/forest_admin_datasource_toolkit/decorators/datasource_decorator.rb index 5285deb02..8eb4be797 100644 --- a/packages/forest_admin_datasource_toolkit/lib/forest_admin_datasource_toolkit/decorators/datasource_decorator.rb +++ b/packages/forest_admin_datasource_toolkit/lib/forest_admin_datasource_toolkit/decorators/datasource_decorator.rb @@ -22,12 +22,11 @@ def live_query_connections end def get_collection(name) - collection = @child_datasource.get_collection(name) - unless @decorators.key?(collection.name) - @decorators[collection.name] = @collection_decorator_class.new(collection, self) + @collections_by_name ||= {} + @collections_by_name[name] ||= begin + collection = @child_datasource.get_collection(name) + @decorators[collection.name] ||= @collection_decorator_class.new(collection, self) end - - @decorators[collection.name] end def render_chart(caller, name, parameters = {})