From 9953726001018dd8cd11d72415e76c6b8c6c6dc2 Mon Sep 17 00:00:00 2001 From: Matt Date: Fri, 24 May 2024 12:00:28 +0200 Subject: [PATCH 1/7] chore: expose plugin to datasource customizer --- .../datasource_customizer.rb | 4 +--- .../datasource_customizer_spec.rb | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/datasource_customizer.rb b/packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/datasource_customizer.rb index bc4d80c73..11cd9cbe4 100644 --- a/packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/datasource_customizer.rb +++ b/packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/datasource_customizer.rb @@ -27,8 +27,6 @@ def datasource(logger) def add_datasource(datasource, options) @stack.queue_customization(lambda { - # TODO: add call logger - if options[:include] || options[:exclude] publication_decorator = Decorators::Publication::PublicationDatasourceDecorator.new(datasource) publication_decorator.keep_collections_matching(options[:include], options[:exclude]) @@ -61,7 +59,7 @@ def add_chart(name, &definition) end def use(plugin, options) - # TODO: to implement + push_customization { plugin.new.run(self, nil, options) } end def customize_collection(name, handle) diff --git a/packages/forest_admin_datasource_customizer/spec/lib/forest_admin_datasource_customizer/datasource_customizer_spec.rb b/packages/forest_admin_datasource_customizer/spec/lib/forest_admin_datasource_customizer/datasource_customizer_spec.rb index f4bf35b6e..2c271f6c1 100644 --- a/packages/forest_admin_datasource_customizer/spec/lib/forest_admin_datasource_customizer/datasource_customizer_spec.rb +++ b/packages/forest_admin_datasource_customizer/spec/lib/forest_admin_datasource_customizer/datasource_customizer_spec.rb @@ -57,5 +57,19 @@ module ForestAdminDatasourceCustomizer expect(datasource.render_chart(caller, 'my_chart')).to eq({ countCurrent: 10, countPrevious: nil }) end end + + context 'when using a plugin' do + it 'adds a plugin' do + customizer = described_class.new + customizer.add_datasource(datasource, {}) + plugin = instance_double(plugin) + allow(plugin).to receive(:new).and_return(plugin) + allow(plugin).to receive(:run).with(customizer, nil, { my_options: 1 }) + + customizer.use(plugin, { my_options: 1 }) + customizer.datasource({}) + expect(plugin).to have_received(:run).with(customizer, nil, { my_options: 1 }) + end + end end end From 235018569b6eec14fec7824c9deb9295b300fa9f Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 28 May 2024 15:37:43 +0200 Subject: [PATCH 2/7] fix: is_primary_key on fetch_fields collection --- .../lib/forest_admin_datasource_active_record/collection.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/forest_admin_datasource_active_record/lib/forest_admin_datasource_active_record/collection.rb b/packages/forest_admin_datasource_active_record/lib/forest_admin_datasource_active_record/collection.rb index 2b5b8e852..7092b2a3a 100644 --- a/packages/forest_admin_datasource_active_record/lib/forest_admin_datasource_active_record/collection.rb +++ b/packages/forest_admin_datasource_active_record/lib/forest_admin_datasource_active_record/collection.rb @@ -47,11 +47,10 @@ def delete(_caller, filter) def fetch_fields @model.columns_hash.each do |column_name, column| - # TODO: check is not sti column field = ForestAdminDatasourceToolkit::Schema::ColumnSchema.new( column_type: get_column_type(@model, column), filter_operators: operators_for_column_type(get_column_type(@model, column)), - is_primary_key: column_name == @model.primary_key, + is_primary_key: column_name == @model.primary_key || @model.primary_key.include?(column_name), is_read_only: false, is_sortable: true, default_value: column.default, From 753bd7a86a4449783663b7526fad92b26ba3f0a5 Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 28 May 2024 15:38:11 +0200 Subject: [PATCH 3/7] fix: attribute action into schema for collection --- .../lib/forest_admin_datasource_toolkit/collection.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/forest_admin_datasource_toolkit/lib/forest_admin_datasource_toolkit/collection.rb b/packages/forest_admin_datasource_toolkit/lib/forest_admin_datasource_toolkit/collection.rb index 350be0378..95a4ef3ee 100644 --- a/packages/forest_admin_datasource_toolkit/lib/forest_admin_datasource_toolkit/collection.rb +++ b/packages/forest_admin_datasource_toolkit/lib/forest_admin_datasource_toolkit/collection.rb @@ -16,9 +16,9 @@ def initialize(datasource, name, native_driver = nil) countable: false, searchable: false, charts: [], - segments: {} + segments: {}, + actions: {} } - @actions = {} end def enable_count @@ -50,9 +50,9 @@ def add_fields(fields) end def add_action(name, action) - raise Exceptions::ForestException, "Action #{name} already defined in collection" if @actions[key] + raise Exceptions::ForestException, "Action #{name} already defined in collection" if @schema[:actions].key?(name) - @actions[name] = action + schema[:actions][name] = action end def render_chart(_caller, name, _record_id) From 93e02a04e15ee529d75c19b88290e528efc25506 Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 28 May 2024 15:39:31 +0200 Subject: [PATCH 4/7] feat: handle collection habtm collection on datasource --- .../datasource.rb | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/packages/forest_admin_datasource_active_record/lib/forest_admin_datasource_active_record/datasource.rb b/packages/forest_admin_datasource_active_record/lib/forest_admin_datasource_active_record/datasource.rb index f0e39d99a..dc5d19f81 100644 --- a/packages/forest_admin_datasource_active_record/lib/forest_admin_datasource_active_record/datasource.rb +++ b/packages/forest_admin_datasource_active_record/lib/forest_admin_datasource_active_record/datasource.rb @@ -5,6 +5,7 @@ class Datasource < ForestAdminDatasourceToolkit::Datasource def initialize(db_config = {}) super() @models = [] + @habtm_models = {} init_orm(db_config) generate end @@ -19,11 +20,52 @@ def generate end def fetch_model(model) - @models << model unless model.abstract_class? || @models.include?(model) || !model.table_exists? + if model.name.start_with?('HABTM_') + build_habtm(model) + else + @models << model unless model.abstract_class? || @models.include?(model) || !model.table_exists? + end end def init_orm(db_config) ActiveRecord::Base.establish_connection(db_config) end + + def build_habtm(model) + if @habtm_models.key?(model.table_name) + @habtm_models[model.table_name].left_reflection = model.right_reflection + # when the second model is added, we can push the HABTM model to the models list + @models << make_through_model( + model.table_name, + [ + @habtm_models[model.table_name].left_reflection, + @habtm_models[model.table_name].right_reflection + ] + ) + else + @habtm_models[model.table_name] = model + end + end + + def make_through_model(table_name, associations) + through_model = Class.new(ActiveRecord::Base) do + class << self + attr_accessor :name, :table_name + end + + def self.add_association(name, options) + belongs_to name, required: false, **options + end + end + + through_model.name = table_name.singularize + through_model.table_name = table_name + through_model.primary_key = [associations[0].foreign_key, associations[1].foreign_key] + associations.each do |association| + through_model.add_association(association.name, association.options) + end + + through_model + end end end From 236087ba70175945f6338178cbcc4d57921f37af Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 28 May 2024 15:39:59 +0200 Subject: [PATCH 5/7] fix(serializer): class_name --- .../serializer/forest_serializer_override.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/forest_admin_agent/lib/forest_admin_agent/serializer/forest_serializer_override.rb b/packages/forest_admin_agent/lib/forest_admin_agent/serializer/forest_serializer_override.rb index 3d40fc99e..cac431839 100644 --- a/packages/forest_admin_agent/lib/forest_admin_agent/serializer/forest_serializer_override.rb +++ b/packages/forest_admin_agent/lib/forest_admin_agent/serializer/forest_serializer_override.rb @@ -60,7 +60,10 @@ def self.find_recursive_relationships(root_object, root_inclusion_tree, results, objects.each do |obj| relation = ForestAdminAgent::Facades::Container.datasource.get_collection(options[:class_name]).schema[:fields][attribute_name] relation_class_name = ForestAdminAgent::Facades::Container.datasource.get_collection(relation.foreign_collection).name - obj_serializer = JSONAPI::Serializer.find_serializer(obj, options) + option_relation = options.clone + option_relation[:class_name] = relation_class_name + obj_serializer = JSONAPI::Serializer.find_serializer(obj, option_relation) + # Use keys of ['posts', '1'] for the results to enforce uniqueness. # Spec: A compound document MUST NOT include more than one resource object for each # type and id pair. @@ -200,7 +203,6 @@ def self.serialize(objects, options = {}) # of the internal special merging logic. find_recursive_relationships(obj, inclusion_tree, relationship_data, passthrough_options) end - result['included'] = relationship_data.map do |_, data| included_passthrough_options = {} included_passthrough_options[:base_url] = passthrough_options[:base_url] From 19e9447c7872455b67532614be950017d8e8ee1d Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 28 May 2024 15:40:29 +0200 Subject: [PATCH 6/7] chore: update query joins relations --- .../lib/forest_admin_datasource_active_record/utils/query.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/forest_admin_datasource_active_record/lib/forest_admin_datasource_active_record/utils/query.rb b/packages/forest_admin_datasource_active_record/lib/forest_admin_datasource_active_record/utils/query.rb index 3ef71e225..3ef097fa1 100644 --- a/packages/forest_admin_datasource_active_record/lib/forest_admin_datasource_active_record/utils/query.rb +++ b/packages/forest_admin_datasource_active_record/lib/forest_admin_datasource_active_record/utils/query.rb @@ -107,9 +107,7 @@ def build_select def apply_select unless @projection.nil? @query = @query.select(@select.join(', ')) - @query = @query.eager_load(@projection.relations.keys.map(&:to_sym)) - # TODO: replace eager_load by joins because eager_load select ALL columns of relation - # @query = @query.joins(@projection.relations.keys.map(&:to_sym)) + @query = @query.joins(@projection.relations.keys.map(&:to_sym)) end @query From 74ce8746f3dd92f7935d9833dc90ec1d6cfe8b0d Mon Sep 17 00:00:00 2001 From: Matt Date: Wed, 29 May 2024 16:54:43 +0200 Subject: [PATCH 7/7] fix: test --- .../datasource_customizer_spec.rb | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/packages/forest_admin_datasource_customizer/spec/lib/forest_admin_datasource_customizer/datasource_customizer_spec.rb b/packages/forest_admin_datasource_customizer/spec/lib/forest_admin_datasource_customizer/datasource_customizer_spec.rb index 2c271f6c1..f4bf35b6e 100644 --- a/packages/forest_admin_datasource_customizer/spec/lib/forest_admin_datasource_customizer/datasource_customizer_spec.rb +++ b/packages/forest_admin_datasource_customizer/spec/lib/forest_admin_datasource_customizer/datasource_customizer_spec.rb @@ -57,19 +57,5 @@ module ForestAdminDatasourceCustomizer expect(datasource.render_chart(caller, 'my_chart')).to eq({ countCurrent: 10, countPrevious: nil }) end end - - context 'when using a plugin' do - it 'adds a plugin' do - customizer = described_class.new - customizer.add_datasource(datasource, {}) - plugin = instance_double(plugin) - allow(plugin).to receive(:new).and_return(plugin) - allow(plugin).to receive(:run).with(customizer, nil, { my_options: 1 }) - - customizer.use(plugin, { my_options: 1 }) - customizer.datasource({}) - expect(plugin).to have_received(:run).with(customizer, nil, { my_options: 1 }) - end - end end end