diff --git a/app/services/forest_liana/filters_parser.rb b/app/services/forest_liana/filters_parser.rb index 69c4c9bf..f9bbc937 100644 --- a/app/services/forest_liana/filters_parser.rb +++ b/app/services/forest_liana/filters_parser.rb @@ -23,8 +23,8 @@ def apply_filters @joins.each do |join| current_resource = @resource.reflect_on_association(join.name).klass current_resource.include(ArelHelpers::Aliases) - current_resource.aliased_as(join.name) do |aliased_resource| - @resource = @resource.joins(ArelHelpers.join_association(@resource, join.name, Arel::Nodes::OuterJoin, aliases: [aliased_resource])) + current_resource.aliased_as("#{join.name}_#{@resource.table_name}") do |aliased_resource| + @resource = @resource.joins(ArelHelpers.join_association(@resource, join.name, Arel::Nodes::OuterJoin, { aliases: [aliased_resource] })) end end @@ -174,14 +174,16 @@ def parse_field_name(field) current_resource = @resource.reflect_on_association(field.split(':').first.to_sym)&.klass raise ForestLiana::Errors::HTTP422Error.new("Field '#{field}' not found") unless current_resource - association = get_association_name_for_condition(field) - quoted_table_name = ActiveRecord::Base.connection.quote_column_name(association) + association = get_association_for_condition(field) + + quoted_table_name = ActiveRecord::Base.connection.quote_table_name("#{association.name}_#{@resource.table_name}") field_name = field.split(':')[1] else quoted_table_name = @resource.quoted_table_name current_resource = @resource field_name = field end + quoted_field_name = ActiveRecord::Base.connection.quote_column_name(field_name) column_found = current_resource.columns.find { |column| column.name == field.split(':').last } @@ -196,7 +198,7 @@ def is_belongs_to(field) field.include?(':') end - def get_association_name_for_condition(field) + def get_association_for_condition(field) field, subfield = field.split(':') association = @resource.reflect_on_association(field.to_sym) @@ -204,7 +206,7 @@ def get_association_name_for_condition(field) @joins << association unless @joins.include? association - association.name + association end # NOTICE: Look for a previous interval condition matching the following: diff --git a/app/services/forest_liana/resources_getter.rb b/app/services/forest_liana/resources_getter.rb index 632a9e81..1387a1cb 100644 --- a/app/services/forest_liana/resources_getter.rb +++ b/app/services/forest_liana/resources_getter.rb @@ -87,6 +87,7 @@ def compute_includes associations_has_one = ForestLiana::QueryHelper.get_one_associations(@resource) includes = associations_has_one.map(&:name) + includes_for_smart_search = [] if @collection && @collection.search_fields diff --git a/app/services/forest_liana/search_query_builder.rb b/app/services/forest_liana/search_query_builder.rb index b45270d5..8079fb4f 100644 --- a/app/services/forest_liana/search_query_builder.rb +++ b/app/services/forest_liana/search_query_builder.rb @@ -189,13 +189,10 @@ def detect_reference(param) ref, field = param.split('.') if ref && field - association = @resource.reflect_on_all_associations - .find {|a| a.name == ref.to_sym } - - referenced_table = association ? association_table_name(association.name) : ref + association = @resource.reflect_on_all_associations().find {|a| a.name == ref.to_sym } ForestLiana::AdapterHelper - .format_column_name(referenced_table, field) + .format_column_name("#{association.name}_#{@resource.table_name}", field) else param end diff --git a/spec/services/forest_liana/resources_getter_spec.rb b/spec/services/forest_liana/resources_getter_spec.rb index b906687c..42712b13 100644 --- a/spec/services/forest_liana/resources_getter_spec.rb +++ b/spec/services/forest_liana/resources_getter_spec.rb @@ -129,6 +129,9 @@ def init_scopes let(:sort) { 'owner.name' } it 'should get only the expected records' do + sql_query = getter.perform.to_sql + p sql_query + getter.perform records = getter.records count = getter.count @@ -153,6 +156,37 @@ def init_scopes expect(count).to eq 5 expect(records.map(&:id)).to eq [1, 4, 5, 3, 2] end + + it 'should include associated table only once' do + sql_query = getter.perform.to_sql + location_includes_count = sql_query.scan('LEFT OUTER JOIN "locations"').count + expect(location_includes_count).to eq(1) + end + + context 'when filters is given' do + let(:filters) { { + field: 'location:id', + operator: 'equal', + value: 1, + }.to_json } + + it 'should get only the expected records' do + getter.perform + records = getter.records + count = getter.count + + expect(records.count).to eq 1 + expect(count).to eq 1 + expect(records.map(&:id)).to eq [1] + end + + it 'should include associated table only once' do + sql_query = getter.perform.to_sql + p sql_query + location_includes_count = sql_query.scan('LEFT OUTER JOIN "locations"').count + expect(location_includes_count).to eq(1) + end + end end describe 'when getting instance dependent associations' do