Nested unions like that are terribly inefficient; that’s why G4MultiUnion was developed. It looks to me like you aren’t apply any rotations to your objects, just positional placements. That should make it much easier to deal with.
With G4MultiUnion the very first solid on the list defines the coordinate system (x,y,z orientation and the location of (0,0,0)). All of these other solids should have their placements done relative to that first one, and when you place the whole solid, the placement specifies where that origin (0,0,0) goes.
It looks like that’s exactly what you’re doing. If I understand right, your “ring1” is the one in the center along the axis. Then ring2, ring3, ring4 are sequentially farther away along -z, and ring5, ring6, ring7 are sequentially along +z.
So with G4MultiUnion, you would do something like:
G4MultiUnion* railgun = new G4MultiUnion("railgun");
railgun->AddNode(ring1, G4Transform3D::Identity);
railgun->AddNode(ring2, G4TranslateZ3D(-300*mm);
railgun->AddNode(ring3, G4TranslateZ3D(-600*mm);
railgun->AddNode(ring4, G4TranslateZ3D(-700*mm);
railgun->AddNode(ring5, G4TranslateZ3D(300*mm);
railgun->AddNode(ring6, G4TranslateZ3D(600*mm);
railgun->AddNode(ring7, G4TranslateZ3D(700*mm);
railgun->AddNode(rod1, G4Translate3D(134.0*mm, 0.0*mm, 0*mm);
railgun->AddNode(rod2, G4Translate3D(-67.0*mm, 116.047*mm, 0*mm);
railgun->AddNode(rod3, G4Translate3D(-67.0*mm, -116.047*mm, 0*mm);