From 22fdcde6db1f40fb8339e144d27c38ec45bdc69d Mon Sep 17 00:00:00 2001 From: GuillaumeCisco Date: Tue, 29 Jun 2021 20:32:03 +0200 Subject: [PATCH 1/5] feat: handle polymorphism support --- .../forest_liana/resource_deserializer.rb | 6 ++++- app/helpers/forest_liana/query_helper.rb | 10 ++++++++- .../forest_liana/serializer_factory.rb | 7 +++++- .../forest_liana/belongs_to_updater.rb | 9 +++++++- .../forest_liana/has_many_associator.rb | 6 ++++- .../forest_liana/has_many_dissociator.rb | 22 ++++++++++++++++--- app/services/forest_liana/has_many_getter.rb | 2 +- app/services/forest_liana/resource_creator.rb | 8 +++++-- app/services/forest_liana/resources_getter.rb | 10 ++++++++- app/services/forest_liana/schema_adapter.rb | 21 +++++++++++++----- app/services/forest_liana/schema_utils.rb | 6 ++++- 11 files changed, 88 insertions(+), 19 deletions(-) diff --git a/app/deserializers/forest_liana/resource_deserializer.rb b/app/deserializers/forest_liana/resource_deserializer.rb index daf3a46a..4526b4f3 100644 --- a/app/deserializers/forest_liana/resource_deserializer.rb +++ b/app/deserializers/forest_liana/resource_deserializer.rb @@ -63,7 +63,11 @@ def extract_relationships # ActionController::Parameters do not inherit from Hash anymore # since Rails 5. if (data.is_a?(Hash) || data.is_a?(ActionController::Parameters)) && data[:id] - @attributes[name] = association.klass.find(data[:id]) + if association.options[:polymorphic] + @attributes[name] = association.active_record.find(data[:id]) + else + @attributes[name] = association.klass.find(data[:id]) + end elsif data.blank? @attributes[name] = nil end diff --git a/app/helpers/forest_liana/query_helper.rb b/app/helpers/forest_liana/query_helper.rb index ce359775..32b63da0 100644 --- a/app/helpers/forest_liana/query_helper.rb +++ b/app/helpers/forest_liana/query_helper.rb @@ -1,8 +1,16 @@ module ForestLiana module QueryHelper + def included(association) + if SchemaUtils.polymorphic?(association) + SchemaUtils.model_included?(association.active_record) + else + SchemaUtils.model_included?(association.klass) + end + end + def self.get_one_associations(resource) SchemaUtils.one_associations(resource) - .select { |association| SchemaUtils.model_included?(association.klass) } + .select { |association| self.included association } end def self.get_one_association_names_symbol(resource) diff --git a/app/serializers/forest_liana/serializer_factory.rb b/app/serializers/forest_liana/serializer_factory.rb index 91c98f84..1c38a84c 100644 --- a/app/serializers/forest_liana/serializer_factory.rb +++ b/app/serializers/forest_liana/serializer_factory.rb @@ -265,7 +265,12 @@ def mixpanel_integration? SchemaUtils.associations(active_record_class).each do |a| begin - if SchemaUtils.model_included?(a.klass) + if SchemaUtils.polymorphic?(a) + included = SchemaUtils.model_included?(a.active_record) + else + included = SchemaUtils.model_included?(a.klass) + end + if included serializer.send(serializer_association(a), a.name) { if [:has_one, :belongs_to].include?(a.macro) begin diff --git a/app/services/forest_liana/belongs_to_updater.rb b/app/services/forest_liana/belongs_to_updater.rb index e36ee2bd..c1ff9d92 100644 --- a/app/services/forest_liana/belongs_to_updater.rb +++ b/app/services/forest_liana/belongs_to_updater.rb @@ -13,7 +13,14 @@ def initialize(resource, association, params) def perform begin @record = @resource.find(@params[:id]) - new_value = @association.klass.find(@data[:id]) if @data && @data[:id] + new_value = nil + if @data && @data[:id] + if @association.options[:polymorphic] + new_value = @association.active_record.find(@data[:id]) + else + new_value = @association.klass.find(@data[:id]) + end + end @record.send("#{@association.name}=", new_value) @record.save diff --git a/app/services/forest_liana/has_many_associator.rb b/app/services/forest_liana/has_many_associator.rb index bef8faf5..aa1acade 100644 --- a/app/services/forest_liana/has_many_associator.rb +++ b/app/services/forest_liana/has_many_associator.rb @@ -13,7 +13,11 @@ def perform if @data.is_a?(Array) @data.each do |record_added| - associated_records << @association.klass.find(record_added[:id]) + if @association.options[:polymorphic] + associated_records << @association.active_record.find(record_added[:id]) + else + associated_records << @association.klass.find(record_added[:id]) + end end end end diff --git a/app/services/forest_liana/has_many_dissociator.rb b/app/services/forest_liana/has_many_dissociator.rb index 905acfc2..91c1cefc 100644 --- a/app/services/forest_liana/has_many_dissociator.rb +++ b/app/services/forest_liana/has_many_dissociator.rb @@ -8,6 +8,14 @@ def initialize(resource, association, params) @data = params['data'] end + def exists(record_id) + if @association.options[:polymorphic] + @association.active_record.exists?(record_id) + else + @association.klass.exists?(record_id) + end + end + def perform @record = @resource.find(@params[:id]) associated_records = @resource.find(@params[:id]).send(@association.name) @@ -25,13 +33,21 @@ def perform if !record_ids.nil? && record_ids.any? if remove_association record_ids.each do |id| - associated_records.delete(@association.klass.find(id)) + if @association.options[:polymorphic] + associated_records.delete(@association.active_record.find(id)) + else + associated_records.delete(@association.klass.find(id)) + end end end if @with_deletion - record_ids = record_ids.select { |record_id| @association.klass.exists?(record_id) } - @association.klass.destroy(record_ids) + record_ids = record_ids.select { |record_id| self.exists record_id } + if @association.options[:polymorphic] + @association.active_record.destroy(record_ids) + else + @association.klass.destroy(record_ids) + end end end end diff --git a/app/services/forest_liana/has_many_getter.rb b/app/services/forest_liana/has_many_getter.rb index ec7fc1eb..a2ffefa5 100644 --- a/app/services/forest_liana/has_many_getter.rb +++ b/app/services/forest_liana/has_many_getter.rb @@ -40,7 +40,7 @@ def compute_includes @includes = @association.klass .reflect_on_all_associations .select do |association| - inclusion = !association.options[:polymorphic] && + inclusion = !SchemaUtils.polymorphic?(association) && SchemaUtils.model_included?(association.klass) && [:belongs_to, :has_and_belongs_to_many].include?(association.macro) diff --git a/app/services/forest_liana/resource_creator.rb b/app/services/forest_liana/resource_creator.rb index 1b9c4d2d..a7a637f0 100644 --- a/app/services/forest_liana/resource_creator.rb +++ b/app/services/forest_liana/resource_creator.rb @@ -18,7 +18,7 @@ def perform end set_has_many_relationships rescue ActiveRecord::StatementInvalid => exception - # NOTICE: SQL request cannot be executed properly + # NOTICE: SQL request cannot be executed properly @errors = [{ detail: exception.cause.error }] rescue ForestLiana::Errors::SerializeAttributeBadFormat => exception @errors = [{ detail: exception.message }] @@ -41,7 +41,11 @@ def set_has_many_relationships if data.is_a?(Array) data.each do |x| existing_records = @record.send(name) - new_record = association.klass.find(x[:id]) + if association.options[:polymorphic] + new_record = association.active_record.find(x[:id]) + else + new_record = association.klass.find(x[:id]) + end if !existing_records.include?(new_record) existing_records << new_record end diff --git a/app/services/forest_liana/resources_getter.rb b/app/services/forest_liana/resources_getter.rb index e73623ce..585084fb 100644 --- a/app/services/forest_liana/resources_getter.rb +++ b/app/services/forest_liana/resources_getter.rb @@ -82,6 +82,14 @@ def records @records.offset(offset).limit(limit).to_a end + def included(association) + if association.options[:polymorphic] + SchemaUtils.model_included?(association.active_record) + else + SchemaUtils.model_included?(association.klass) + end + end + def compute_includes associations_has_one = ForestLiana::QueryHelper.get_one_associations(@resource) @@ -94,7 +102,7 @@ def compute_includes .map { |field| field.split('.').first.to_sym } includes_has_many = SchemaUtils.many_associations(@resource) - .select { |association| SchemaUtils.model_included?(association.klass) } + .select { |association| self.included association } .map(&:name) includes_for_smart_search = includes_for_smart_search & includes_has_many diff --git a/app/services/forest_liana/schema_adapter.rb b/app/services/forest_liana/schema_adapter.rb index b5daa051..cb5a71be 100644 --- a/app/services/forest_liana/schema_adapter.rb +++ b/app/services/forest_liana/schema_adapter.rb @@ -240,7 +240,12 @@ def add_associations SchemaUtils.associations(@model).each do |association| begin # NOTICE: Delete the association if the targeted model is excluded. - if !SchemaUtils.model_included?(association.klass) + if SchemaUtils.polymorphic?(association) + included = SchemaUtils.model_included?(association.active_record) + else + included = SchemaUtils.model_included?(association.klass) + end + if !included field = collection.fields.find do |x| x[:field] == association.foreign_key end @@ -273,13 +278,17 @@ def inverse_of(association) end def automatic_inverse_of(association) - name = association.active_record.name.demodulize.underscore + if association.options[:polymorphic] + association.active_record.name.demodulize.underscore.pluralize + else + name = association.active_record.name.demodulize.underscore - inverse_association = association.klass.reflections.keys.find do |k| - k.to_s == name || k.to_s == name.pluralize - end + inverse_association = association.klass.reflections.keys.find do |k| + k.to_s == name || k.to_s == name.pluralize + end - inverse_association.try(:to_s) + inverse_association.try(:to_s) + end end def get_schema_for_column(column) diff --git a/app/services/forest_liana/schema_utils.rb b/app/services/forest_liana/schema_utils.rb index d973f4b6..97286796 100644 --- a/app/services/forest_liana/schema_utils.rb +++ b/app/services/forest_liana/schema_utils.rb @@ -4,7 +4,11 @@ class SchemaUtils def self.associations(active_record_class) active_record_class.reflect_on_all_associations.select do |association| begin - !polymorphic?(association) && !is_active_type?(association.klass) + if polymorphic?(association) + !is_active_type?(association.active_record) + else + !is_active_type?(association.klass) + end rescue FOREST_LOGGER.warn "Unknown association #{association.name} on class #{active_record_class.name}" false From bb375711654ca1504eb57833c4a52082ba1161eb Mon Sep 17 00:00:00 2001 From: GuillaumeCisco Date: Wed, 30 Jun 2021 11:17:14 +0200 Subject: [PATCH 2/5] refactor: refactor and fix tests --- .../forest_liana/associations_controller.rb | 12 +++++----- .../forest_liana/resource_deserializer.rb | 8 ++----- app/helpers/forest_liana/query_helper.rb | 10 +-------- .../forest_liana/serializer_factory.rb | 6 +---- .../forest_liana/belongs_to_updater.rb | 6 +---- .../forest_liana/has_many_associator.rb | 6 +---- .../forest_liana/has_many_dissociator.rb | 22 +++---------------- app/services/forest_liana/has_many_getter.rb | 2 +- .../forest_liana/leaderboard_stat_getter.rb | 2 +- app/services/forest_liana/resource_creator.rb | 6 +---- app/services/forest_liana/resources_getter.rb | 10 +-------- app/services/forest_liana/schema_adapter.rb | 17 +++++--------- app/services/forest_liana/schema_utils.rb | 14 +++++++----- 13 files changed, 34 insertions(+), 87 deletions(-) diff --git a/app/controllers/forest_liana/associations_controller.rb b/app/controllers/forest_liana/associations_controller.rb index b56770ec..a7186ae5 100644 --- a/app/controllers/forest_liana/associations_controller.rb +++ b/app/controllers/forest_liana/associations_controller.rb @@ -15,7 +15,7 @@ def index respond_to do |format| format.json { render_jsonapi(getter) } - format.csv { render_csv(getter, @association.klass) } + format.csv { render_csv(getter, SchemaUtils.association_ref(@association)) } end rescue => error FOREST_LOGGER.error "Association Index error: #{error}\n#{format_stacktrace(error)}" @@ -104,21 +104,21 @@ def resource_params end def is_sti_model? - @is_sti_model ||= (@association.klass.inheritance_column.present? && - @association.klass.columns.any? { |column| column.name == @association.klass.inheritance_column }) + @is_sti_model ||= (SchemaUtils.association_ref(@association).inheritance_column.present? && + SchemaUtils.association_ref(@association).columns.any? { |column| column.name == SchemaUtils.association_ref(@association).inheritance_column }) end def get_record record - is_sti_model? ? record.becomes(@association.klass) : record + is_sti_model? ? record.becomes(SchemaUtils.association_ref(@association)) : record end def render_jsonapi getter - fields_to_serialize = fields_per_model(params[:fields], @association.klass) + fields_to_serialize = fields_per_model(params[:fields], SchemaUtils.association_ref(@association)) records = getter.records.map { |record| get_record(record) } includes = getter.includes_for_serialization if fields_to_serialize && includes.length > 0 - association_name = ForestLiana.name_for(@association.klass) + association_name = ForestLiana.name_for(SchemaUtils.association_ref(@association)) fields_to_serialize[association_name] += ",#{includes.join(',')}" end diff --git a/app/deserializers/forest_liana/resource_deserializer.rb b/app/deserializers/forest_liana/resource_deserializer.rb index 4526b4f3..576e6b67 100644 --- a/app/deserializers/forest_liana/resource_deserializer.rb +++ b/app/deserializers/forest_liana/resource_deserializer.rb @@ -57,17 +57,13 @@ def extract_relationships #if data.blank? #@attributes[name] = nil #else - #@attributes[name] = association.klass.find(data[:id]) + #@attributes[name] = SchemaUtils.association_ref(association).find(data[:id]) #end # ActionController::Parameters do not inherit from Hash anymore # since Rails 5. if (data.is_a?(Hash) || data.is_a?(ActionController::Parameters)) && data[:id] - if association.options[:polymorphic] - @attributes[name] = association.active_record.find(data[:id]) - else - @attributes[name] = association.klass.find(data[:id]) - end + @attributes[name] = SchemaUtils.association_ref(association).find(data[:id]) elsif data.blank? @attributes[name] = nil end diff --git a/app/helpers/forest_liana/query_helper.rb b/app/helpers/forest_liana/query_helper.rb index 32b63da0..f6599cb7 100644 --- a/app/helpers/forest_liana/query_helper.rb +++ b/app/helpers/forest_liana/query_helper.rb @@ -1,16 +1,8 @@ module ForestLiana module QueryHelper - def included(association) - if SchemaUtils.polymorphic?(association) - SchemaUtils.model_included?(association.active_record) - else - SchemaUtils.model_included?(association.klass) - end - end - def self.get_one_associations(resource) SchemaUtils.one_associations(resource) - .select { |association| self.included association } + .select { |association| SchemaUtils.model_included?(SchemaUtils.association_ref(association)) } end def self.get_one_association_names_symbol(resource) diff --git a/app/serializers/forest_liana/serializer_factory.rb b/app/serializers/forest_liana/serializer_factory.rb index 1c38a84c..adf8dd71 100644 --- a/app/serializers/forest_liana/serializer_factory.rb +++ b/app/serializers/forest_liana/serializer_factory.rb @@ -265,11 +265,7 @@ def mixpanel_integration? SchemaUtils.associations(active_record_class).each do |a| begin - if SchemaUtils.polymorphic?(a) - included = SchemaUtils.model_included?(a.active_record) - else - included = SchemaUtils.model_included?(a.klass) - end + included = SchemaUtils.model_included?(SchemaUtils.association_ref(a)) if included serializer.send(serializer_association(a), a.name) { if [:has_one, :belongs_to].include?(a.macro) diff --git a/app/services/forest_liana/belongs_to_updater.rb b/app/services/forest_liana/belongs_to_updater.rb index c1ff9d92..8e459afa 100644 --- a/app/services/forest_liana/belongs_to_updater.rb +++ b/app/services/forest_liana/belongs_to_updater.rb @@ -15,11 +15,7 @@ def perform @record = @resource.find(@params[:id]) new_value = nil if @data && @data[:id] - if @association.options[:polymorphic] - new_value = @association.active_record.find(@data[:id]) - else - new_value = @association.klass.find(@data[:id]) - end + new_value = SchemaUtils.association_ref(@association).find(@data[:id]) end @record.send("#{@association.name}=", new_value) diff --git a/app/services/forest_liana/has_many_associator.rb b/app/services/forest_liana/has_many_associator.rb index aa1acade..33ae8db1 100644 --- a/app/services/forest_liana/has_many_associator.rb +++ b/app/services/forest_liana/has_many_associator.rb @@ -13,11 +13,7 @@ def perform if @data.is_a?(Array) @data.each do |record_added| - if @association.options[:polymorphic] - associated_records << @association.active_record.find(record_added[:id]) - else - associated_records << @association.klass.find(record_added[:id]) - end + associated_records << SchemaUtils.association_ref(@association).find(record_added[:id]) end end end diff --git a/app/services/forest_liana/has_many_dissociator.rb b/app/services/forest_liana/has_many_dissociator.rb index 91c1cefc..fa771120 100644 --- a/app/services/forest_liana/has_many_dissociator.rb +++ b/app/services/forest_liana/has_many_dissociator.rb @@ -8,14 +8,6 @@ def initialize(resource, association, params) @data = params['data'] end - def exists(record_id) - if @association.options[:polymorphic] - @association.active_record.exists?(record_id) - else - @association.klass.exists?(record_id) - end - end - def perform @record = @resource.find(@params[:id]) associated_records = @resource.find(@params[:id]).send(@association.name) @@ -33,21 +25,13 @@ def perform if !record_ids.nil? && record_ids.any? if remove_association record_ids.each do |id| - if @association.options[:polymorphic] - associated_records.delete(@association.active_record.find(id)) - else - associated_records.delete(@association.klass.find(id)) - end + associated_records.delete(SchemaUtils.association_ref(@association).find(id)) end end if @with_deletion - record_ids = record_ids.select { |record_id| self.exists record_id } - if @association.options[:polymorphic] - @association.active_record.destroy(record_ids) - else - @association.klass.destroy(record_ids) - end + record_ids = record_ids.select { |record_id| SchemaUtils.association_ref(@association).exists?(record_id) } + SchemaUtils.association_ref(@association).destroy(record_ids) end end end diff --git a/app/services/forest_liana/has_many_getter.rb b/app/services/forest_liana/has_many_getter.rb index a2ffefa5..c6911aee 100644 --- a/app/services/forest_liana/has_many_getter.rb +++ b/app/services/forest_liana/has_many_getter.rb @@ -37,7 +37,7 @@ def records private def compute_includes - @includes = @association.klass + @includes = SchemaUtils.association_ref(@association) .reflect_on_all_associations .select do |association| inclusion = !SchemaUtils.polymorphic?(association) && diff --git a/app/services/forest_liana/leaderboard_stat_getter.rb b/app/services/forest_liana/leaderboard_stat_getter.rb index b331df44..6ddf49e9 100644 --- a/app/services/forest_liana/leaderboard_stat_getter.rb +++ b/app/services/forest_liana/leaderboard_stat_getter.rb @@ -3,7 +3,7 @@ class LeaderboardStatGetter < StatGetter def initialize(resource, params) @resource = resource @params = params - @model_relationship = @resource.reflect_on_association(@params[:relationship_field]).klass + @model_relationship = @resource.reflect_on_association(@params[:relationship_field]).klass compute_includes() @label_field = @params[:label_field] @aggregate = @params[:aggregate].downcase diff --git a/app/services/forest_liana/resource_creator.rb b/app/services/forest_liana/resource_creator.rb index a7a637f0..1c16c286 100644 --- a/app/services/forest_liana/resource_creator.rb +++ b/app/services/forest_liana/resource_creator.rb @@ -41,11 +41,7 @@ def set_has_many_relationships if data.is_a?(Array) data.each do |x| existing_records = @record.send(name) - if association.options[:polymorphic] - new_record = association.active_record.find(x[:id]) - else - new_record = association.klass.find(x[:id]) - end + new_record = SchemaUtils.association_ref(association).find(x[:id]) if !existing_records.include?(new_record) existing_records << new_record end diff --git a/app/services/forest_liana/resources_getter.rb b/app/services/forest_liana/resources_getter.rb index 585084fb..abbf1f1a 100644 --- a/app/services/forest_liana/resources_getter.rb +++ b/app/services/forest_liana/resources_getter.rb @@ -82,14 +82,6 @@ def records @records.offset(offset).limit(limit).to_a end - def included(association) - if association.options[:polymorphic] - SchemaUtils.model_included?(association.active_record) - else - SchemaUtils.model_included?(association.klass) - end - end - def compute_includes associations_has_one = ForestLiana::QueryHelper.get_one_associations(@resource) @@ -102,7 +94,7 @@ def compute_includes .map { |field| field.split('.').first.to_sym } includes_has_many = SchemaUtils.many_associations(@resource) - .select { |association| self.included association } + .select { |association| SchemaUtils.model_included?(SchemaUtils.association_ref(association)) } .map(&:name) includes_for_smart_search = includes_for_smart_search & includes_has_many diff --git a/app/services/forest_liana/schema_adapter.rb b/app/services/forest_liana/schema_adapter.rb index cb5a71be..0822431e 100644 --- a/app/services/forest_liana/schema_adapter.rb +++ b/app/services/forest_liana/schema_adapter.rb @@ -240,11 +240,7 @@ def add_associations SchemaUtils.associations(@model).each do |association| begin # NOTICE: Delete the association if the targeted model is excluded. - if SchemaUtils.polymorphic?(association) - included = SchemaUtils.model_included?(association.active_record) - else - included = SchemaUtils.model_included?(association.klass) - end + included = SchemaUtils.model_included?(SchemaUtils.association_ref(association)) if !included field = collection.fields.find do |x| x[:field] == association.foreign_key @@ -278,11 +274,10 @@ def inverse_of(association) end def automatic_inverse_of(association) - if association.options[:polymorphic] - association.active_record.name.demodulize.underscore.pluralize + name = SchemaUtils.association_ref(association).name.demodulize.underscore + if SchemaUtils.polymorphic?(association) + name.pluralize.try(:to_s) else - name = association.active_record.name.demodulize.underscore - inverse_association = association.klass.reflections.keys.find do |k| k.to_s == name || k.to_s == name.pluralize end @@ -322,7 +317,7 @@ def get_schema_for_association(association) field: association.name.to_s, type: get_type_for_association(association), relationship: get_relationship_type(association), - reference: "#{ForestLiana.name_for(association.klass)}.id", + reference: "#{ForestLiana.name_for(SchemaUtils.association_ref(association))}.id", inverse_of: inverse_of(association), is_filterable: !is_many_association(association), is_sortable: true, @@ -509,7 +504,7 @@ def add_validations(column_schema, column) end def get_reference_for(association) - if association.options[:polymorphic] == true + if SchemaUtils.polymorphic?(association) '*.id' else "#{ForestLiana.name_for(association.klass)}.id" diff --git a/app/services/forest_liana/schema_utils.rb b/app/services/forest_liana/schema_utils.rb index 97286796..d39c0416 100644 --- a/app/services/forest_liana/schema_utils.rb +++ b/app/services/forest_liana/schema_utils.rb @@ -4,11 +4,7 @@ class SchemaUtils def self.associations(active_record_class) active_record_class.reflect_on_all_associations.select do |association| begin - if polymorphic?(association) - !is_active_type?(association.active_record) - else - !is_active_type?(association.klass) - end + !is_active_type?(SchemaUtils.association_ref(association)) rescue FOREST_LOGGER.warn "Unknown association #{association.name} on class #{active_record_class.name}" false @@ -62,6 +58,14 @@ def self.polymorphic?(association) association.options[:polymorphic] end + def self.association_ref(association) + if self.polymorphic?(association) + association.active_record + else + association.klass + end + end + def self.find_model_from_abstract_class(abstract_class, collection_name) abstract_class.subclasses.find do |subclass| if subclass.abstract_class? From d548fa1eb7d1522d197467a0c1d29340bdffb10a Mon Sep 17 00:00:00 2001 From: GuillaumeCisco Date: Wed, 30 Jun 2021 12:20:40 +0200 Subject: [PATCH 3/5] refactor: use better method for founding inverse of polymorphic --- app/services/forest_liana/schema_adapter.rb | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/app/services/forest_liana/schema_adapter.rb b/app/services/forest_liana/schema_adapter.rb index 0822431e..a2960211 100644 --- a/app/services/forest_liana/schema_adapter.rb +++ b/app/services/forest_liana/schema_adapter.rb @@ -240,8 +240,7 @@ def add_associations SchemaUtils.associations(@model).each do |association| begin # NOTICE: Delete the association if the targeted model is excluded. - included = SchemaUtils.model_included?(SchemaUtils.association_ref(association)) - if !included + if !SchemaUtils.model_included?(SchemaUtils.association_ref(association)) field = collection.fields.find do |x| x[:field] == association.foreign_key end @@ -274,10 +273,16 @@ def inverse_of(association) end def automatic_inverse_of(association) - name = SchemaUtils.association_ref(association).name.demodulize.underscore if SchemaUtils.polymorphic?(association) - name.pluralize.try(:to_s) + active_models = ActiveRecord::Base.descendants + active_models.each do |model| + a = model.reflect_on_all_associations.select{|a| a.options[:as] == association.name } + unless a.empty? + return a.first.name + end + end else + name = association.active_record.name.demodulize.underscore inverse_association = association.klass.reflections.keys.find do |k| k.to_s == name || k.to_s == name.pluralize end From 5478fa07c5f5930139e8f87f663e9fbb49ea8acd Mon Sep 17 00:00:00 2001 From: GuillaumeCisco Date: Wed, 30 Jun 2021 14:16:25 +0200 Subject: [PATCH 4/5] refactor: fix cognitive complexity --- app/services/forest_liana/schema_adapter.rb | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/app/services/forest_liana/schema_adapter.rb b/app/services/forest_liana/schema_adapter.rb index a2960211..562d4ace 100644 --- a/app/services/forest_liana/schema_adapter.rb +++ b/app/services/forest_liana/schema_adapter.rb @@ -272,15 +272,19 @@ def inverse_of(association) automatic_inverse_of(association) end + def polymorphic_inverse_of(association) + active_models = ActiveRecord::Base.descendants + active_models.each do |model| + a = model.reflect_on_all_associations.select{|a| a.options[:as] == association.name } + unless a.empty? + return a.first.name + end + end + end + def automatic_inverse_of(association) if SchemaUtils.polymorphic?(association) - active_models = ActiveRecord::Base.descendants - active_models.each do |model| - a = model.reflect_on_all_associations.select{|a| a.options[:as] == association.name } - unless a.empty? - return a.first.name - end - end + polymorphic_inverse_of(association) else name = association.active_record.name.demodulize.underscore inverse_association = association.klass.reflections.keys.find do |k| From ebd88c5d6472e580f2085a3ea3ccdfd3802fa0c6 Mon Sep 17 00:00:00 2001 From: GuillaumeCisco Date: Wed, 30 Jun 2021 16:06:17 +0200 Subject: [PATCH 5/5] chore: fix eager load with includes --- app/helpers/forest_liana/query_helper.rb | 2 +- app/serializers/forest_liana/serializer_factory.rb | 3 +-- app/services/forest_liana/belongs_to_updater.rb | 5 +---- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/app/helpers/forest_liana/query_helper.rb b/app/helpers/forest_liana/query_helper.rb index f6599cb7..7d7c7fc6 100644 --- a/app/helpers/forest_liana/query_helper.rb +++ b/app/helpers/forest_liana/query_helper.rb @@ -2,7 +2,7 @@ module ForestLiana module QueryHelper def self.get_one_associations(resource) SchemaUtils.one_associations(resource) - .select { |association| SchemaUtils.model_included?(SchemaUtils.association_ref(association)) } + .select { |association| !SchemaUtils.polymorphic?(association) && SchemaUtils.model_included?(association.klass) } end def self.get_one_association_names_symbol(resource) diff --git a/app/serializers/forest_liana/serializer_factory.rb b/app/serializers/forest_liana/serializer_factory.rb index adf8dd71..93d8dac4 100644 --- a/app/serializers/forest_liana/serializer_factory.rb +++ b/app/serializers/forest_liana/serializer_factory.rb @@ -265,8 +265,7 @@ def mixpanel_integration? SchemaUtils.associations(active_record_class).each do |a| begin - included = SchemaUtils.model_included?(SchemaUtils.association_ref(a)) - if included + if SchemaUtils.model_included?(SchemaUtils.association_ref(a)) serializer.send(serializer_association(a), a.name) { if [:has_one, :belongs_to].include?(a.macro) begin diff --git a/app/services/forest_liana/belongs_to_updater.rb b/app/services/forest_liana/belongs_to_updater.rb index 8e459afa..519ab2e5 100644 --- a/app/services/forest_liana/belongs_to_updater.rb +++ b/app/services/forest_liana/belongs_to_updater.rb @@ -13,10 +13,7 @@ def initialize(resource, association, params) def perform begin @record = @resource.find(@params[:id]) - new_value = nil - if @data && @data[:id] - new_value = SchemaUtils.association_ref(@association).find(@data[:id]) - end + new_value = SchemaUtils.association_ref(@association).find(@data[:id]) if @data && @data[:id] @record.send("#{@association.name}=", new_value) @record.save