Skip to content

Commit a4c43a7

Browse files
gabriel-bolbotinaWithalion
authored andcommitted
Added old logic to handle displayed foreign key and update the UI and… (#4428)
1 parent c597587 commit a4c43a7

3 files changed

Lines changed: 88 additions & 5 deletions

File tree

app/attributes/attributecontroller.cpp

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,37 @@ void AttributeController::prefillRelationReferenceField()
129129
{
130130
QVariant foreignKey = mParentController->featureLayerPair().feature().attribute( fieldPair.referencedField() );
131131
QString referencingField = fieldPair.referencingField();
132-
const QgsVectorLayer *childLayer = mLinkedRelation.referencingLayer();
133-
if ( childLayer )
132+
133+
std::shared_ptr<FormItem> formItem;
134+
for ( const auto &item : mFormItems )
135+
{
136+
if ( item->field().name() == referencingField )
137+
{
138+
formItem = item;
139+
break;
140+
}
141+
}
142+
143+
if ( formItem )
134144
{
135-
const int fieldIndex = childLayer->fields().lookupField( referencingField );
136-
if ( fieldIndex != -1 )
145+
//if the field is in the form, setFormValue updates both the feature attribute and UI
146+
setFormValue( formItem->id(), foreignKey );
147+
}
148+
else
149+
{
150+
// if the field is not displayed in the form, then set the attribute directly on the feature
151+
const QgsVectorLayer *childLayer = mLinkedRelation.referencingLayer();
152+
if ( childLayer )
153+
{
154+
const int fieldIndex = childLayer->fields().lookupField( referencingField );
155+
if ( fieldIndex != -1 )
156+
mFeatureLayerPair.featureRef().setAttribute( fieldIndex, foreignKey );
157+
else
158+
CoreUtils::log( "Attribute Controller - Relations", QStringLiteral( "Could not find field index for field %1" ).arg( referencingField ) );
159+
}
160+
else
137161
{
138-
mFeatureLayerPair.featureRef().setAttribute( fieldIndex, foreignKey );
162+
CoreUtils::log( "Attribute Controller - Relations", QStringLiteral( "Invalid child layer for relation %1" ).arg( mLinkedRelation.name() ) );
139163
}
140164
}
141165
}

app/test/testattributecontroller.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,3 +1219,56 @@ void TestAttributeController::testPhotoSketchingSave()
12191219
QCOMPARE( f.attribute( testCaseResult.fieldIdx ), testCaseResult.expectedNewFieldValue );
12201220
}
12211221
}
1222+
1223+
void TestAttributeController::testPrefillRelationReferenceField()
1224+
{
1225+
QString projectDir = TestUtils::testDataDir() + "/planes";
1226+
QVERIFY( QgsProject::instance()->read( projectDir + "/quickapp_project.qgs" ) );
1227+
1228+
QgsVectorLayer *airportsLayer = dynamic_cast<QgsVectorLayer *>(
1229+
QgsProject::instance()->mapLayersByName( QStringLiteral( "airports" ) ).at( 0 ) );
1230+
QVERIFY( airportsLayer && airportsLayer->isValid() );
1231+
1232+
QgsVectorLayer *towersLayer = dynamic_cast<QgsVectorLayer *>(
1233+
QgsProject::instance()->mapLayersByName( QStringLiteral( "airport-towers" ) ).at( 0 ) );
1234+
QVERIFY( towersLayer && towersLayer->isValid() );
1235+
1236+
QgsRelation relation = QgsProject::instance()->relationManager()->relation(
1237+
QStringLiteral( "airport_to_airport_fk_airports_3_fid" ) );
1238+
QVERIFY( relation.isValid() );
1239+
1240+
// parent controller holds an existing airports feature
1241+
QgsFeature parentFeature = airportsLayer->getFeature( 1 );
1242+
QVERIFY( parentFeature.isValid() );
1243+
1244+
AttributeController parentController;
1245+
parentController.setFeatureLayerPair( FeatureLayerPair( parentFeature, airportsLayer ) );
1246+
1247+
// child controller holds a new empty airport-towers feature
1248+
QgsFeature childFeature;
1249+
childFeature.setValid( true );
1250+
childFeature.setFields( towersLayer->fields(), true );
1251+
1252+
AttributeController childController;
1253+
childController.setFeatureLayerPair( FeatureLayerPair( childFeature, towersLayer ) );
1254+
childController.setLinkedRelation( relation );
1255+
childController.setParentController( &parentController ); // triggers prefillRelationReferenceField
1256+
1257+
// find the airport_fk FormItem in the child controller
1258+
const FormItem *fkItem = nullptr;
1259+
const TabItem *tab = childController.tabItem( 0 );
1260+
QVERIFY( tab );
1261+
for ( const QUuid &id : tab->formItems() )
1262+
{
1263+
const FormItem *item = childController.formItem( id );
1264+
if ( item && item->field().name() == QLatin1String( "airport_fk" ) )
1265+
{
1266+
fkItem = item;
1267+
break;
1268+
}
1269+
}
1270+
1271+
// compare that the rawValue is updated after setting the linked relation
1272+
QVERIFY( fkItem );
1273+
QCOMPARE( fkItem->rawValue(), parentFeature.attribute( QStringLiteral( "fid" ) ) );
1274+
}

app/test/testattributecontroller.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ class TestAttributeController: public QObject
3636
* the sketches play nicely with renaming expressions and metadata gets copied too.
3737
*/
3838
void testPhotoSketchingSave();
39+
40+
/**
41+
* Test that prefillRelationReferenceField sets the rawValue of the FK field in the child controller
42+
* to the parent feature's referenced field value (FID).
43+
*/
44+
void testPrefillRelationReferenceField();
3945
};
4046

4147
#endif // TESTATTRIBUTECONTROLLER_H

0 commit comments

Comments
 (0)