For triggers however you need to replace the trigger wholesale, so you end up with several versions of the trigger on your file system and need to check each migration file to see what the latest definition of the trigger is (for tables rails normally creates a separate file with the current state of the database after running a migration, so you have relatively easy access to the latest state of table definitions).
Granted, this is an issue for any system comprised of distributed components. Though I think the pain is more acute when it's the source of truth.
One way around is downtime or going all in on stored procedures for all work, or at least all writes.
The other wrinkle is that the trigger has to be rolled back when reverting code. And some shops are not diligent about maintaining down procedures. There is also the possiblity of rolling back migrations out of the order they were run, so you might not get back to a consistent state.
I think some folks above may literally have meant they put the trigger code in the migration file itself. Or I'm way off base.
How would you create triggers if you didn't create an SQL file with the trigger code, and running that at some point? And since it's in a file, wouldn't you check that into version control?
Or are you actually typing in triggers manually in the Postgres command line?