A lot of people set debugger breakpoints by inserting "debugger" or "binding.pry" manually. That also sucks because you can't easily disable a breakpoint after you've reached it. And of course it's an idiotic way of inserting breakpoints, because you can't just detach the debugger - you have to delete every breakpoint if you want the the server to just run.
The language itself is also badly designed. A single-line block uses { }, but when it's multiple lines, it has to be changed to "do" and "end" - why? Do/end is dumb for the other constructs - VSCode can easily jump to a matching paren/bracket/brace, but not to the matching do/end. Who thought |x| was a good idea? Look at C# to see how this should be done. That's just scratching the surface, there are so many shitty features in this language.
Then on top of this, you have Sorbet - grafting type checking onto the code, but outside the language. It's about 100 times uglier than just having typing built into the language. Today I learned that you can't provide a Sorbet sig for a module_function - Rubocop doesn't understand it. Rubocop runs as part of "git commit", so you can't do anything that Rubocop doesn't like.
All of this is so shitty and amateur and primitive and backwards. Right now is not a good time for finding a new job as a software engineer, otherwise I'd be out of here looking for a job where I can use a real language with real tools that work and improve productivity rather than killing productivity like the Ruby circus.
Rails has some nice features, but for every bit of productivity gain that it gives you, there's about 10x as much negative impact on productivity.