Skip to content

Commit c38e224

Browse files
authored
fix: key conflicts in fields for same-collection smart relations (#755)
1 parent 67afc84 commit c38e224

File tree

2 files changed

+94
-1
lines changed

2 files changed

+94
-1
lines changed

app/controllers/forest_liana/application_controller.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,11 @@ def fields_per_model(params_fields, model)
188188
else
189189
smart_relations.each do |smart_relation|
190190
if smart_relation[:field].to_s == relation_name
191-
fields[relation_name] = relation_fields
191+
if smart_relation[:reference].split('.').first == params[:collection]
192+
fields[relation_name] = relation_fields
193+
else
194+
fields[smart_relation[:reference].split('.').first] = relation_fields
195+
end
192196
end
193197
end
194198
end

spec/requests/actions_controller_spec.rb

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,4 +606,93 @@
606606
controller.send(:serialize_models, records, options)
607607
end
608608
end
609+
610+
describe 'fields_per_model method' do
611+
let(:model) { Island }
612+
let(:collection_name) { 'Island' }
613+
614+
before do
615+
forest_collection = double('forest_collection')
616+
allow(ForestLiana).to receive(:apimap).and_return([forest_collection])
617+
allow(forest_collection).to receive(:name).and_return(collection_name)
618+
end
619+
620+
context 'with smart relations pointing to external models' do
621+
it 'should use reference model name as key for external smart relations' do
622+
smart_relations = [
623+
{
624+
field: :organization,
625+
reference: 'Api__OrganizationsView.id',
626+
is_virtual: true,
627+
is_searchable: false,
628+
type: 'String'
629+
}
630+
]
631+
632+
forest_collection = double('forest_collection')
633+
allow(forest_collection).to receive(:name).and_return(collection_name)
634+
allow(forest_collection).to receive(:fields_smart_belongs_to).and_return(smart_relations)
635+
allow(ForestLiana).to receive(:apimap).and_return([forest_collection])
636+
637+
params_fields = ActionController::Parameters.new({
638+
'organization' => 'name'
639+
})
640+
641+
mock_params = ActionController::Parameters.new({
642+
collection: 'Island',
643+
fields: { 'Island' => 'id,name', 'organization' => 'name'},
644+
page: { 'number' => '1', 'size' => '10' },
645+
searchExtended: '0',
646+
sort: '-id',
647+
timezone: 'Europe/Paris'
648+
})
649+
allow(controller).to receive(:params).and_return(mock_params)
650+
651+
result = controller.send(:fields_per_model, params_fields, model)
652+
653+
expect(result).to have_key('Api__OrganizationsView')
654+
expect(result['Api__OrganizationsView']).to eq('name')
655+
expect(result).not_to have_key('organization')
656+
end
657+
end
658+
659+
context 'with smart relations pointing to same collection (self-reference)' do
660+
it 'should use relation name as key for self-referencing smart relations' do
661+
smart_relations = [
662+
{
663+
field: :parent_island,
664+
reference: 'Island.id',
665+
is_virtual: true,
666+
is_searchable: false,
667+
type: 'String'
668+
}
669+
]
670+
671+
forest_collection = double('forest_collection')
672+
allow(forest_collection).to receive(:name).and_return(collection_name)
673+
allow(forest_collection).to receive(:fields_smart_belongs_to).and_return(smart_relations)
674+
allow(ForestLiana).to receive(:apimap).and_return([forest_collection])
675+
676+
params_fields = ActionController::Parameters.new({
677+
'parent_island' => 'name'
678+
})
679+
680+
mock_params = ActionController::Parameters.new({
681+
collection: 'Island',
682+
fields: { 'Island' => 'id,name', 'parent_island' => 'name'},
683+
page: { 'number' => '1', 'size' => '10' },
684+
searchExtended: '0',
685+
sort: '-id',
686+
timezone: 'Europe/Paris'
687+
})
688+
allow(controller).to receive(:params).and_return(mock_params)
689+
690+
result = controller.send(:fields_per_model, params_fields, model)
691+
692+
expect(result).to have_key('parent_island')
693+
expect(result['parent_island']).to eq('name')
694+
expect(result).not_to have_key('Island')
695+
end
696+
end
697+
end
609698
end

0 commit comments

Comments
 (0)