Lots of app developers need simple and easy to setup database access so that they can focus on the parts of their app that matters. Not having an ORM means that a decent chunk of them will move on to another language/ecosystem that has the libraries they want.
If it's still being debated, isn't that a good indication that there's no perfect solution for every use case?
ORMs are likely more straightforward when you know you're not going to need to do anything advanced, but get in the way when you need fine grained control for example.
Ultimately it's useless for both.
I contrast that with technologies that are easy to use when you're small, but then let you layer additional pieces on later when you need to scale, without needing to redo everything.
What most people discover to be the greatest benefit of using an ORM is the "mapper" bit (converting tabulated data into an object graph and visa versa) and, to a lesser degree, change-tracking.
Somewhat ironically, the overwhelming majority of the time criticism of ORMs is directed at neither of the above, instead pointing to query performance.
You can have data mapping, you can have change-tracking, you can even have schema migrations without opting-in to the pain points many ORMs introduce because these are all somewhat orthogonal concerns.
At the end of the day there is very little to be saved between writing:
users->where(u => u.name === "John")
and SELECT * FROM users WHERE [name] = 'John'
Often, as queries become more complex, the SQL is actually a shorter expression than whatever query DSL comes with the ORM.I think that the "query builders" though are just one piece of the ORM that you mention, alongside the change-tracking, data mapping, etc. Having a decent query builder that isn't abstracting away too much of the underlying sql (essentially just mapping 1-to-1) plus data mapping are the sweet spot for me personally.
Interestingly, it is this exact property (composition) that creates the most common problems when using an ORM.
Composition is often at odds with optimization.
Under the hood many[0] ORMs simply construct a query similar to my example above and then convert result set of tabulated strings to the appropriate types (usually using reflection).
This means two things:
First, that the "type-safety" portions of an ORM are really located in the "mapping" code, so not really related to querying.
And second: you don't really have type safety. A database schema could change at any time and break the code even if static analysis seems to think it should work.
[0] Notable exceptions are languages that offer type providers (e.g. F#) but I digress
There are really two things I want to put out there:
1) My opinion is that about 90% of your standard, day-to-day queries work just fine in a good ORM. The developer _should_ know enough about the DB schema and SQL to handle the other 10%. (In our 10 y/o enterprise software, the only queries we really drop down into SQL for are complex windowed reporting queries.)
2) Eloquent ORM is... different. It's probably the best I've seen. I wish it existed in other languages. Sequelize, which may be the "best" in the JS ecosystem, doesn't hold a candle to Eloquent, IMO.
In particular, I think relations are great to work with in Eloquent.
That's only true if you need the "relational" part of an ORM - mapping a flat list of values onto a structure of related objects. If you only need to map a flat list of values onto a single object's fields, you don't need a query builder.
I wrote a C# SQLite library along those lines: raw SQL and simple object mapping. https://github.com/zmj/sqlite-fast
Why is that a benefit though? Why would I rather learn some custom query builder-specific DSL when SQL is at least mostly standardized pretty much everywhere. The use of template strings in JS can get rid of all the problems of just plain string concatenation for SQL (e.g. it can prevent SQL injection, enable safe dynamic queries, etc.)
However, Eloquent absolutely is a class above the rest. Honestly one of the best I've ever worked with.