Skip to content
Merged
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
30 changes: 24 additions & 6 deletions app/serializers/forest_liana/serializer_factory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,6 @@ def relationship_related_link(attribute_name)

if ret[:href].blank?
begin
if @options[:include].try(:include?, attribute_name.to_s) &&
!SchemaHelper.is_smart_field?(object.class, attribute_name.to_s)

object.send(attribute_name)
end

SchemaUtils.many_associations(object.class).each do |a|
if a.name == attribute_name
ret[:href] = "/forest/#{ForestLiana.name_for(object.class)}/#{object.id}/relationships/#{attribute_name}"
Expand All @@ -137,6 +131,30 @@ def relationship_related_link(attribute_name)
ret
end

def has_one_relationships
return {} if self.class.to_one_associations.nil?
data = {}
self.class.to_one_associations.each do |attribute_name, attr_data|
relation = object.class.reflect_on_all_associations.find { |a| a.name == attribute_name }

next if !should_include_attr?(attribute_name, attr_data)

unless relation.polymorphic?
relation_class_name = ForestLiana.name_for(relation.klass).demodulize

if object.send(relation.foreign_key.to_sym) &&
@options[:fields][relation_class_name]&.size == 1 &&
@options[:fields][relation_class_name]&.include?(relation.klass.primary_key.to_sym)

attr_data[:attr_or_block] = proc { relation.klass.new(relation.klass.primary_key => object.send(relation.foreign_key.to_sym)) }
end
end

data[attribute_name] = attr_data
end
data
end

private

def intercom_integration?
Expand Down
3 changes: 2 additions & 1 deletion app/services/forest_liana/base_getter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ def includes_for_serialization

def compute_includes
@includes = ForestLiana::QueryHelper.get_one_association_names_symbol(@resource)
@optional_includes = []
end

def optimize_record_loading(resource, records, force_preload = true)
polymorphic, preload_loads = analyze_associations(resource)
result = records.eager_load(@includes.uniq - preload_loads - polymorphic)
result = records.eager_load(@includes.uniq - preload_loads - polymorphic - @optional_includes)

result = result.preload(preload_loads) if Rails::VERSION::MAJOR >= 7 && force_preload

Expand Down
2 changes: 2 additions & 0 deletions app/services/forest_liana/has_many_getter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ def records
private

def compute_includes
@optional_includes = []

@includes = @association.klass
.reflect_on_all_associations
.select do |association|
Expand Down
42 changes: 27 additions & 15 deletions app/services/forest_liana/resources_getter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def self.get_ids_from_request(params, user)

def perform
polymorphic_association, preload_loads = analyze_associations(@resource)
includes = @includes.uniq - polymorphic_association - preload_loads
includes = @includes.uniq - polymorphic_association - preload_loads - @optional_includes
has_smart_fields = @params[:fields][@collection_name].split(',').any? do |field|
ForestLiana::SchemaHelper.is_smart_field?(@resource, field)
end
Expand Down Expand Up @@ -132,26 +132,38 @@ def columns_for_cross_database_association(association_name)

def compute_includes
associations_has_one = ForestLiana::QueryHelper.get_one_associations(@resource)
@optional_includes = []
if @field_names_requested
includes = associations_has_one.map do |association|
association_name = association.name.to_s

includes = associations_has_one.map(&:name)
includes_for_smart_search = []
if @params[:fields].key?(association_name) &&
@params[:fields][association_name].split(',').size == 1 &&
@params[:fields][association_name].split(',').include?(association.klass.primary_key)

if @collection && @collection.search_fields
includes_for_smart_search = @collection.search_fields
.select { |field| field.include? '.' }
.map { |field| field.split('.').first.to_sym }
@field_names_requested << association.foreign_key
@optional_includes << association.name
end

includes_has_many = SchemaUtils.many_associations(@resource)
.select { |association| SchemaUtils.model_included?(association.klass) }
.map(&:name)
association.name
end

includes_for_smart_search = includes_for_smart_search & includes_has_many
end
includes_for_smart_search = []
if @collection && @collection.search_fields
includes_for_smart_search = @collection.search_fields
.select { |field| field.include? '.' }
.map { |field| field.split('.').first.to_sym }

includes_has_many = SchemaUtils.many_associations(@resource)
.select { |association| SchemaUtils.model_included?(association.klass) }
.map(&:name)

includes_for_smart_search = includes_for_smart_search & includes_has_many
end

if @field_names_requested
@includes = (includes & @field_names_requested).concat(includes_for_smart_search)
else
@includes = includes
@includes = associations_has_one.map(&:name)
end
end

Expand Down Expand Up @@ -298,7 +310,7 @@ def pagination?

def compute_select_fields
select = ['_forest_admin_eager_load']
@params[:fields][@collection_name].split(',').each do |path|
@field_names_requested.each do |path|
association = get_one_association(path)
if association
while association.options[:through]
Expand Down
Loading