| Overall, I think the article is pretty good. ORMs fall under the same category as garbage collection or try/catch exceptions: it is a tool. Tools solve a lot of common cases, but that doesn't relieve the developer from understanding what is actually happening under the hood. * Garbage collection solves pointer problems, but the developer has to know what is being allocated and when to prevent churning memory.
* Try/catch exceptions solves breaking the tie between where exceptions can occur and where exceptions can be handled, but the developer still has to determine if all of the exceptions are being handled.
* An ORM solves relating objects to data persistence, but the developer still has to know what relations weren't covered in the original query after the objects are used. > Active Record struggles with this, and that’s why we refactored our billing
> subscription query. Whenever we got results we didn’t expect, we’d have to
> inspect the rendered SQL query, rerun it, and then translate the SQL error
> into Active Record changes. This back-and-forth process undermined the
> original purpose of using Active Record, which was to avoid interfacing
> directly with the SQL database. This is where I disagree. ActiveRecord was meant to map objects you have to your relational database, hence Object Relational Mapper. It is not a reporting interface. But it is reasonable to get around this. One way is to get a lot more specific in building the query with `arel`. Alternatively, open the raw connection and execute SQL with `ActiveRecord::Base.connection.execute`. The disconnect here is believing that ActiveRecord solves billing/reporting SQL statements. It does not. It solves mapping objects. If your access pattern doesn't match (reports, N+1, GraphQL) then you have to understand the tool well enough to create your own mapping solution (custom SQL, preloading/scoping, data loader). I remember when Java was considered really, really slow. The guy used a code example to prove a point. I rewrote the code to stop relying on the GC allocating/freeing data structures over and over and sped the program up by 400% on that alone. |