Skip to content

Commit 695bb7c

Browse files
authored
Fix some testing issues including flappy tests, simplify quoting generated SQL strings (#1363)
* Refine when config.active_record.sqlite3.represent_boolean_as_integer is set Tests with rails > 6.1.1 breaks with this option * Update rails 6.1 tested version * Add quoting for fields in built up sql * Remove tests for generated sql statements These are changing with new rails versions and it's creating a lot of false failures * Remove tests for generated sql statements using joins_left * Fix default sort for when empty array is provided Fixes issue with relationship requests not getting a default sort * Add helper methods for generating sql fields with aliases and quotes
1 parent 856f139 commit 695bb7c

File tree

6 files changed

+56
-103
lines changed

6 files changed

+56
-103
lines changed

.github/workflows/ruby.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
- 2.7.2
3131
- 3.0.0
3232
rails:
33-
- 6.1.1
33+
- 6.1.3.1
3434
- 6.0.3.4
3535
- 5.2.4.4
3636
- 5.1.7

lib/jsonapi/active_relation_resource.rb

Lines changed: 53 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,11 @@ def find_fragments(filters, options = {})
121121
# This alias is going to be resolve down to the model's table name and will not actually be an alias
122122
resource_table_alias = resource_klass._table_name
123123

124-
pluck_fields = [Arel.sql("#{concat_table_field(resource_table_alias, resource_klass._primary_key)} AS #{resource_table_alias}_#{resource_klass._primary_key}")]
124+
pluck_fields = [sql_field_with_alias(resource_table_alias, resource_klass._primary_key)]
125125

126126
cache_field = attribute_to_model_field(:_cache_field) if options[:cache]
127127
if cache_field
128-
pluck_fields << Arel.sql("#{concat_table_field(resource_table_alias, cache_field[:name])} AS #{resource_table_alias}_#{cache_field[:name]}")
128+
pluck_fields << sql_field_with_alias(resource_table_alias, cache_field[:name])
129129
end
130130

131131
linkage_fields = []
@@ -141,10 +141,10 @@ def find_fragments(filters, options = {})
141141

142142
linkage_fields << {relationship_name: name,
143143
resource_klass: klass,
144-
field: "#{concat_table_field(linkage_table_alias, primary_key)} AS #{linkage_table_alias}_#{primary_key}",
145-
alias: "#{linkage_table_alias}_#{primary_key}"}
144+
field: sql_field_with_alias(linkage_table_alias, primary_key),
145+
alias: alias_table_field(linkage_table_alias, primary_key)}
146146

147-
pluck_fields << Arel.sql("#{concat_table_field(linkage_table_alias, primary_key)} AS #{linkage_table_alias}_#{primary_key}")
147+
pluck_fields << sql_field_with_alias(linkage_table_alias, primary_key)
148148
end
149149
else
150150
klass = linkage_relationship.resource_klass
@@ -153,10 +153,10 @@ def find_fragments(filters, options = {})
153153

154154
linkage_fields << {relationship_name: name,
155155
resource_klass: klass,
156-
field: "#{concat_table_field(linkage_table_alias, primary_key)} AS #{linkage_table_alias}_#{primary_key}",
157-
alias: "#{linkage_table_alias}_#{primary_key}"}
156+
field: sql_field_with_alias(linkage_table_alias, primary_key),
157+
alias: alias_table_field(linkage_table_alias, primary_key)}
158158

159-
pluck_fields << Arel.sql("#{concat_table_field(linkage_table_alias, primary_key)} AS #{linkage_table_alias}_#{primary_key}")
159+
pluck_fields << sql_field_with_alias(linkage_table_alias, primary_key)
160160
end
161161
end
162162

@@ -165,7 +165,7 @@ def find_fragments(filters, options = {})
165165
attributes.try(:each) do |attribute|
166166
model_field = resource_klass.attribute_to_model_field(attribute)
167167
model_fields[attribute] = model_field
168-
pluck_fields << Arel.sql("#{concat_table_field(resource_table_alias, model_field[:name])} AS #{resource_table_alias}_#{model_field[:name]}")
168+
pluck_fields << sql_field_with_alias(resource_table_alias, model_field[:name])
169169
end
170170

171171
sort_fields = options.dig(:_relation_helper_options, :sort_fields)
@@ -423,13 +423,13 @@ def find_related_monomorphic_fragments(source_fragments, relationship, options,
423423
resource_table_alias = join_manager.join_details_by_relationship(relationship)[:alias]
424424

425425
pluck_fields = [
426-
Arel.sql("#{_table_name}.#{_primary_key} AS source_id"),
427-
Arel.sql("#{concat_table_field(resource_table_alias, resource_klass._primary_key)} AS #{resource_table_alias}_#{resource_klass._primary_key}")
426+
Arel.sql("#{_table_name}.#{_primary_key} AS \"source_id\""),
427+
sql_field_with_alias(resource_table_alias, resource_klass._primary_key)
428428
]
429429

430430
cache_field = resource_klass.attribute_to_model_field(:_cache_field) if options[:cache]
431431
if cache_field
432-
pluck_fields << Arel.sql("#{concat_table_field(resource_table_alias, cache_field[:name])} AS #{resource_table_alias}_#{cache_field[:name]}")
432+
pluck_fields << sql_field_with_alias(resource_table_alias, cache_field[:name])
433433
end
434434

435435
linkage_fields = []
@@ -444,15 +444,15 @@ def find_related_monomorphic_fragments(source_fragments, relationship, options,
444444

445445
linkage_table_alias = join_manager.join_details_by_polymorphic_relationship(linkage_relationship, resource_type)[:alias]
446446
primary_key = klass._primary_key
447-
pluck_fields << Arel.sql("#{concat_table_field(linkage_table_alias, primary_key)} AS #{linkage_table_alias}_#{primary_key}")
447+
pluck_fields << sql_field_with_alias(linkage_table_alias, primary_key)
448448
end
449449
else
450450
klass = linkage_relationship.resource_klass
451451
linkage_fields << {relationship_name: name, resource_klass: klass}
452452

453453
linkage_table_alias = join_manager.join_details_by_relationship(linkage_relationship)[:alias]
454454
primary_key = klass._primary_key
455-
pluck_fields << Arel.sql("#{concat_table_field(linkage_table_alias, primary_key)} AS #{linkage_table_alias}_#{primary_key}")
455+
pluck_fields << sql_field_with_alias(linkage_table_alias, primary_key)
456456
end
457457
end
458458

@@ -461,7 +461,7 @@ def find_related_monomorphic_fragments(source_fragments, relationship, options,
461461
attributes.try(:each) do |attribute|
462462
model_field = resource_klass.attribute_to_model_field(attribute)
463463
model_fields[attribute] = model_field
464-
pluck_fields << Arel.sql("#{concat_table_field(resource_table_alias, model_field[:name])} AS #{resource_table_alias}_#{model_field[:name]}")
464+
pluck_fields << sql_field_with_alias(resource_table_alias, model_field[:name])
465465
end
466466

467467
sort_fields = options.dig(:_relation_helper_options, :sort_fields)
@@ -557,9 +557,9 @@ def find_related_polymorphic_fragments(source_fragments, relationship, options,
557557
related_type = concat_table_field(_table_name, relationship.polymorphic_type)
558558

559559
pluck_fields = [
560-
Arel.sql("#{primary_key} AS #{_table_name}_#{_primary_key}"),
561-
Arel.sql("#{related_key} AS #{_table_name}_#{relationship.foreign_key}"),
562-
Arel.sql("#{related_type} AS #{_table_name}_#{relationship.polymorphic_type}")
560+
Arel.sql("#{primary_key} AS #{alias_table_field(_table_name, _primary_key)}"),
561+
Arel.sql("#{related_key} AS #{alias_table_field(_table_name, relationship.foreign_key)}"),
562+
Arel.sql("#{related_type} AS #{alias_table_field(_table_name, relationship.polymorphic_type)}")
563563
]
564564

565565
# Get the additional fields from each relation. There's a limitation that the fields must exist in each relation
@@ -584,7 +584,7 @@ def find_related_polymorphic_fragments(source_fragments, relationship, options,
584584

585585
cache_offset = relation_index
586586
if cache_field
587-
pluck_fields << Arel.sql("#{concat_table_field(table_alias, cache_field[:name])} AS cache_#{type}_#{cache_field[:name]}")
587+
pluck_fields << sql_field_with_alias(table_alias, cache_field[:name])
588588
relation_index+= 1
589589
end
590590

@@ -593,7 +593,7 @@ def find_related_polymorphic_fragments(source_fragments, relationship, options,
593593
attributes.try(:each) do |attribute|
594594
model_field = related_klass.attribute_to_model_field(attribute)
595595
model_fields[attribute] = model_field
596-
pluck_fields << Arel.sql("#{concat_table_field(table_alias, model_field[:name])} AS #{table_alias}_#{model_field[:name]}")
596+
pluck_fields << sql_field_with_alias(table_alias, model_field[:name])
597597
relation_index+= 1
598598
end
599599

@@ -630,15 +630,15 @@ def find_related_polymorphic_fragments(source_fragments, relationship, options,
630630

631631
linkage_table_alias = join_manager.join_details_by_polymorphic_relationship(linkage_relationship, resource_type)[:alias]
632632
primary_key = klass._primary_key
633-
pluck_fields << Arel.sql("#{concat_table_field(linkage_table_alias, primary_key)} AS #{linkage_table_alias}_#{primary_key}")
633+
pluck_fields << sql_field_with_alias(linkage_table_alias, primary_key)
634634
end
635635
else
636636
klass = linkage_relationship.resource_klass
637637
linkage_fields << {relationship: linkage_relationship, resource_klass: klass}
638638

639639
linkage_table_alias = join_manager.join_details_by_relationship(linkage_relationship)[:alias]
640640
primary_key = klass._primary_key
641-
pluck_fields << Arel.sql("#{concat_table_field(linkage_table_alias, primary_key)} AS #{linkage_table_alias}_#{primary_key}")
641+
pluck_fields << sql_field_with_alias(linkage_table_alias, primary_key)
642642
end
643643
end
644644

@@ -804,22 +804,50 @@ def concat_table_field(table, field, quoted = false)
804804
if table.blank? || field.to_s.include?('.')
805805
# :nocov:
806806
if quoted
807-
"\"#{field.to_s}\""
807+
quote(field)
808+
else
809+
field.to_s
810+
end
811+
# :nocov:
812+
else
813+
if quoted
814+
"#{quote(table)}.#{quote(field)}"
815+
else
816+
# :nocov:
817+
"#{table.to_s}.#{field.to_s}"
818+
# :nocov:
819+
end
820+
end
821+
end
822+
823+
def sql_field_with_alias(table, field, quoted = true)
824+
Arel.sql("#{concat_table_field(table, field, quoted)} AS #{alias_table_field(table, field, quoted)}")
825+
end
826+
827+
def alias_table_field(table, field, quoted = false)
828+
if table.blank? || field.to_s.include?('.')
829+
# :nocov:
830+
if quoted
831+
quote(field)
808832
else
809833
field.to_s
810834
end
811835
# :nocov:
812836
else
813837
if quoted
814838
# :nocov:
815-
"\"#{table.to_s}\".\"#{field.to_s}\""
839+
quote("#{table.to_s}_#{field.to_s}")
816840
# :nocov:
817841
else
818-
"#{table.to_s}.#{field.to_s}"
842+
"#{table.to_s}_#{field.to_s}"
819843
end
820844
end
821845
end
822846

847+
def quote(field)
848+
"\"#{field.to_s}\""
849+
end
850+
823851
def apply_filters(records, filters, options = {})
824852
if filters
825853
filters.each do |filter, value|

lib/jsonapi/basic_resource.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1057,7 +1057,7 @@ def default_sort
10571057
end
10581058

10591059
def construct_order_options(sort_params)
1060-
sort_params ||= default_sort
1060+
sort_params = default_sort if sort_params.blank?
10611061

10621062
return {} unless sort_params
10631063

test/test_helper.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class TestApp < Rails::Application
6262
config.active_support.halt_callback_chains_on_return_false = false
6363
config.active_record.time_zone_aware_types = [:time, :datetime]
6464
config.active_record.belongs_to_required_by_default = false
65-
unless Rails::VERSION::MAJOR == 5 && Rails::VERSION::MINOR < 2
65+
unless Rails::VERSION::MAJOR == 5 && Rails::VERSION::MINOR < 2 || Rails::VERSION::MAJOR == 6 && Rails::VERSION::MINOR >= 1
6666
config.active_record.sqlite3.represent_boolean_as_integer = true
6767
end
6868
end

test/unit/active_relation_resource_finder/active_record_adapter_test.rb

Lines changed: 0 additions & 18 deletions
This file was deleted.

0 commit comments

Comments
 (0)