Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions app/services/forest_liana/resources_getter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,19 @@ def self.get_ids_from_request(params, user)
end

def perform
polymorphic_association, preload_loads = analyze_associations(@resource)
includes = @includes.uniq - polymorphic_association - preload_loads - @optional_includes
has_smart_fields = Array(@params.dig(:fields, @collection_name)&.split(',')).any? do |field|
ForestLiana::SchemaHelper.is_smart_field?(@resource, field)
end
@records = optimize_record_loading(@resource, @records, false)

if includes.empty? || has_smart_fields
@records = optimize_record_loading(@resource, @records, false)
else
select = compute_select_fields
@records = optimize_record_loading(@resource, @records, false).references(includes).select(*select)
if ForestLiana.optimize_query_select_fields
polymorphic_association, preload_loads = analyze_associations(@resource)
includes = @includes.uniq - polymorphic_association - preload_loads - @optional_includes
has_smart_fields = Array(@params.dig(:fields, @collection_name)&.split(',')).any? do |field|
ForestLiana::SchemaHelper.is_smart_field?(@resource, field)
end

if includes.any? && !has_smart_fields
select = compute_select_fields
@records = @records.references(includes).select(*select)
end
end

@records
Expand Down
2 changes: 2 additions & 0 deletions lib/forest_liana.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ module UserSpace
mattr_accessor :meta
mattr_accessor :logger
mattr_accessor :reporter
mattr_accessor :optimize_query_select_fields
# TODO: Remove once lianas prior to 2.0.0 are not supported anymore.
mattr_accessor :names_old_overriden

Expand All @@ -42,6 +43,7 @@ module UserSpace
self.meta = {}
self.logger = nil
self.reporter = nil
self.optimize_query_select_fields = true

@config_dir = 'lib/forest_liana/**/*.rb'

Expand Down
49 changes: 48 additions & 1 deletion spec/services/forest_liana/resources_getter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ def clean_database
describe 'records eager loading' do
let(:resource) { Product }
let(:fields) { { resource.name => 'id,name,manufacturer', 'manufacturer' => 'name' } }
let(:expected_selected_resource_attributes) { %w[id name manufacturer_id] }

shared_context 'resource current_database' do
before do
Expand Down Expand Up @@ -117,9 +118,31 @@ def connection.current_database
end
end

shared_examples 'filtered resource fields selection' do
it 'selects only the fields requested from the main resource' do
expected_non_selected_attributes = Product.attribute_names - expected_selected_resource_attributes

full_sql = getter.perform.to_sql

# Extract only the SELECT column list (between SELECT and the first FROM)
select_match = full_sql.match(/SELECT\s+(.*?)\s+FROM/i)
expect(select_match).not_to be_nil
select_columns_sql = select_match[1]

expected_selected_resource_attributes.each do |attribute|
expect(select_columns_sql).to include(%Q{"products"."#{attribute}"})
end

expected_non_selected_attributes.each do |attribute|
expect(select_columns_sql).not_to include(%Q{"products"."#{attribute}"})
end
end
end

context 'when the connections do not support current_database' do
include_examples 'left outer join'
include_examples 'records'
include_examples 'filtered resource fields selection'
end

context 'when the included association uses a different database connection' do
Expand Down Expand Up @@ -151,6 +174,30 @@ def association_connection.current_database

include_examples 'left outer join'
include_examples 'records'
include_examples 'filtered resource fields selection'
end

context 'when the configuration to optimize query select fields is disabled' do
let(:expected_selected_resource_attributes) { Product.attribute_names }

before do
allow(ForestLiana).to receive(:optimize_query_select_fields).and_return(false)
end

include_examples 'records'

it 'selects all fields from the main resource' do
full_sql = getter.perform.to_sql

# Extract only the SELECT column list (between SELECT and the first FROM)
select_match = full_sql.match(/SELECT\s+(.*?)\s+FROM/i)
expect(select_match).not_to be_nil
select_columns_sql = select_match[1]

expected_selected_resource_attributes.each do |attribute|
expect(select_columns_sql).to include(%Q{"products"."#{attribute}"})
end
end
end
end

Expand Down Expand Up @@ -651,4 +698,4 @@ def association_connection.current_database
end
end
end
end
end