Gates just denote the local connectivity between modules and possible interconnections via wired channels.
Say you have a node with two output gates, because he is connected to two nodes via channels.
You would have to specify in the send method, which gate the packet should be sent over.
Traversing a network now is a different thing. Here, we use higher layer addresses (like MAC or IP addresses in real life). Those are used, exchanged and compared via routing protocols to map a certain path through the network.
For example, you have three nodes A, B and C, connected in a line (A <-> B <-> C). When gets a packet from A that has the higher layer destination address C, he needs to find out, to which output gate he must forward this packet. This is often done with an interface and routing table. The interface table collects the available interfaces and their higher layer addresses, the routing tables collects other known nodes and addresses and their associated interface.
When B reads the higher layer destination address from the packet, he sees that it is addresses to C. He then looks in his routing table, finds out over which interface he needs to forward the packet and (at the end) uses the send method with the correct gate index / ID / name to send the packet over the correct output gate to C.
That's the basic approach, a bit simplified of course. The send method with the gate index is used on the lowest layer to actually send the module over a gate. The send methods of higher layers (like IP) have a different syntax, where destination addresses might be passed directly via the send command or indirectly (included in the actual message/packet that is passed along with the send command).