What is controversial about AR?
How it represents rows as objects. How it makes people think about them.
How it conflates modelling the domain with database structure.
https://www.google.co.uk/search?q=activerecord+vs+datamapper
A row is the DBMS's model of an entity in the domain. An object is an object-oriented programming language's model of an entity in the domain.
Representing domain entities as objects in the PL that are backed by rows in a database relation (view or table), which is what the Active Record pattern does, is reasonable.
> How it conflates modelling the domain with database structure.
Modelling the domain should drive both application and database structure; the Active Record pattern doesn't promote anything bad I can see there.
There are particular choices in database design that are encouraged by the path of least resistance in some Active Record implementations and related tooling that are, perhaps, not so great.
There's why we disagree. I believe the DBMS's model shouldn't be conflated with the application's model. Sometimes the row is an entity in the domain; however consider a normalised data structure, where the entity as the application understands it may span a couple of tables. Or involve data from another source.
My understanding is ORMs were originally developed to handle the mapping between domains, and https://en.wikipedia.org/wiki/Object-relational_impedance_mi....
DataMappers also shine when working against a legacy database or one that cannot be changed. But ActiveRecord is a heck of a lot simpler to work with.
> Modelling the domain should drive both application and database structure
I am luke-warm on this coupling; too often it leads to the application structured around the database representation, as you point out. Sometimes this is sensible (e.g. a data-processing system), but in my experience it comes back to bite later on.
I'm interested to hear your experience - do your application models match the database structure?
foreach($things as $thing) {
$thing->setValue('new value');
}
and then looping through 10000 rows to do that, instead of using an UPDATE query.I think the best criticism of ActiveRecord (and ORM in general) is performance, but it's only relevant on medium-to-large websites. It is a fantastic design pattern for prototyping, and good enough for production on small-to-medium websites as long as there are caching layers above it.
Slavishly mapping a row in a database table to an application object is bad. Off the top of my head, an example could be a Product, where the tables are something like:
product - main product details
product_option - options (e.g. Size, Colour)
product_option_values - values for that specific option instance
In my application I don't care about the database structure - whether the tables are normalised or storing everything in one huge serialized blob (or CouchDB, or ElasticSearch or... you get the picture). Instead you want to get the options and save changes straight back when editing the product.Now this is where my example breaks down as the Product needs to 'know' about what options are available (either to provide a nice API or to know what to display in the UI) and my schema doesn't allow for that (save a Product.getAllOptions() method) but I'll leave that as an exercise for my reader :)
Maybe someday we (Royal we of all software engineers who build tools other engineers use) will learn there's a limit to abstraction layers applicability and put hard breaks into the code when that happens.
I guess one shouldn't complain, the more tools allow developers to shoot themselves in the foot and not feel the pain until the leg needs to be cut off, the more variety of positions that will be open for engineers who've been there done that.