Skip to content

Commit 9b476ee

Browse files
[*] Has Many Relationships - Fix sorting on hasMany fields in related data (#341)
* [*] Has Many Relationships - Fix sorting on hasMany fields in related data. * Fixed tests * Fix sorting * Updated CHANGELOG.md * Improve performance * Update CHANGELOG.md Co-Authored-By: Arnaud Besnier <[email protected]> * Fix CHANGELOG * Fix the rebase * Remove trailing spaces Co-authored-by: Arnaud Besnier <[email protected]>
1 parent e910a38 commit 9b476ee

File tree

5 files changed

+64
-84
lines changed

5 files changed

+64
-84
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# Change Log
22

33
## [Unreleased]
4+
### Added
5+
- Has Many Relationships - Enable sorting on belongsTo relationship columns in related data.
6+
47
### Fixed
58
- Technical - Fix CI build.
69

app/services/forest_liana/has_many_getter.rb

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,13 @@ def initialize(resource, association, params)
1919
end
2020

2121
def perform
22-
@records = search_query
23-
@records = sort_query
22+
@records = @search_query_builder.perform(@records)
2423
end
2524

2625
def count
2726
@records_count = @records.count
2827
end
2928

30-
def search_query
31-
@search_query_builder.perform(@records)
32-
end
33-
3429
def query_for_batch
3530
@records
3631
end
@@ -64,10 +59,6 @@ def field_names_requested
6459
.map { |name| name.to_sym }
6560
end
6661

67-
def association_table_name
68-
model_association.try(:table_name)
69-
end
70-
7162
def model_association
7263
@resource.reflect_on_association(@params[:association_name].to_sym).klass
7364
end
@@ -101,23 +92,5 @@ def limit
10192
def pagination?
10293
@params[:page] && @params[:page][:number]
10394
end
104-
105-
def sort_query
106-
if @params[:sort]
107-
field = @params[:sort]
108-
order = detect_sort_order(field)
109-
field.slice!(0) if order == :desc
110-
111-
@records = @records
112-
.order("#{association_table_name}.#{field} #{order.upcase}")
113-
else
114-
@records
115-
end
116-
end
117-
118-
def detect_sort_order(field)
119-
return (if field[0] == '-' then :desc else :asc end)
120-
end
121-
12295
end
12396
end

app/services/forest_liana/resources_getter.rb

Lines changed: 1 addition & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ def initialize(resource, params)
2121

2222
def perform
2323
@records = @records.eager_load(@includes)
24-
@records_sorted = sort_query
2524
end
2625

2726
def count
@@ -35,7 +34,7 @@ def query_for_batch
3534
end
3635

3736
def records
38-
@records_sorted.offset(offset).limit(limit).to_a
37+
@records.offset(offset).limit(limit).to_a
3938
end
4039

4140
def compute_includes
@@ -114,36 +113,6 @@ def search_query
114113
@search_query_builder.perform(@records)
115114
end
116115

117-
def sort_query
118-
column = nil
119-
order = 'DESC'
120-
121-
if @params[:sort]
122-
@params[:sort].split(',').each do |field|
123-
order_detected = detect_sort_order(@params[:sort])
124-
order = order_detected.upcase
125-
field.slice!(0) if order_detected == :desc
126-
127-
field = detect_reference(field)
128-
if field.index('.').nil?
129-
column = ForestLiana::AdapterHelper.format_column_name(@resource.table_name, field)
130-
else
131-
column = field
132-
end
133-
end
134-
elsif @resource.column_names.include?('created_at')
135-
column = ForestLiana::AdapterHelper.format_column_name(@resource.table_name, 'created_at')
136-
elsif @resource.column_names.include?('id')
137-
column = ForestLiana::AdapterHelper.format_column_name(@resource.table_name, 'id')
138-
end
139-
140-
if column
141-
@records = @records.order(Arel.sql("#{column} #{order}"))
142-
else
143-
@records
144-
end
145-
end
146-
147116
def prepare_query
148117
@records = get_resource
149118

@@ -172,28 +141,6 @@ def prepare_query
172141
@records = search_query
173142
end
174143

175-
def detect_sort_order(field)
176-
return (if field[0] == '-' then :desc else :asc end)
177-
end
178-
179-
def detect_reference(param)
180-
ref, field = param.split('.')
181-
182-
if ref && field
183-
association = @resource.reflect_on_all_associations
184-
.find {|a| a.name == ref.to_sym }
185-
186-
if association
187-
ForestLiana::AdapterHelper
188-
.format_column_name(association.table_name, field)
189-
else
190-
param
191-
end
192-
else
193-
param
194-
end
195-
end
196-
197144
def association?(field)
198145
@resource.reflect_on_association(field.to_sym).present?
199146
end

app/services/forest_liana/search_query_builder.rb

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def perform(resource)
3434
end
3535
end
3636
end
37-
37+
@records = sort_query
3838
@records
3939
end
4040

@@ -146,6 +146,63 @@ def search_param
146146
@records
147147
end
148148

149+
def association_table_name(name)
150+
QueryHelper.get_tables_associated_to_relations_name(@records).detect { |key, values|
151+
break key if Array(values).include?(name)
152+
}
153+
154+
end
155+
156+
def sort_query
157+
column = nil
158+
order = 'DESC'
159+
160+
if @params[:sort]
161+
@params[:sort].split(',').each do |field|
162+
order_detected = detect_sort_order(@params[:sort])
163+
order = order_detected.upcase
164+
field.slice!(0) if order_detected == :desc
165+
166+
field = detect_reference(field)
167+
if field.index('.').nil?
168+
column = ForestLiana::AdapterHelper.format_column_name(@resource.table_name, field)
169+
else
170+
column = field
171+
end
172+
end
173+
elsif @resource.column_names.include?('created_at')
174+
column = ForestLiana::AdapterHelper.format_column_name(@resource.table_name, 'created_at')
175+
elsif @resource.column_names.include?('id')
176+
column = ForestLiana::AdapterHelper.format_column_name(@resource.table_name, 'id')
177+
end
178+
179+
if column
180+
@records = @records.order(Arel.sql("#{column} #{order}"))
181+
else
182+
@records
183+
end
184+
end
185+
186+
def detect_reference(param)
187+
ref, field = param.split('.')
188+
189+
if ref && field
190+
association = @resource.reflect_on_all_associations
191+
.find {|a| a.name == ref.to_sym }
192+
193+
referenced_table = association ? association_table_name(association.name) : ref
194+
195+
ForestLiana::AdapterHelper
196+
.format_column_name(referenced_table, field)
197+
else
198+
param
199+
end
200+
end
201+
202+
def detect_sort_order(field)
203+
return (if field[0] == '-' then :desc else :asc end)
204+
end
205+
149206
def association_search_condition table_name, column_name
150207
column_name = format_column_name(table_name, column_name)
151208
"LOWER(#{column_name}) LIKE :search_value_for_string"

test/services/forest_liana/has_many_getter_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class HasManyGetterTest < ActiveSupport::TestCase
3131

3232
assert records.count == 3
3333
assert count = 3
34-
assert records.first.id == 1
34+
assert records.first.id == 7
3535
end
3636

3737
test 'HasMany Getter with sort parameter' do

0 commit comments

Comments
 (0)