I'll preface this by saying that I'm excited about the Merb merger - seems like a huge boost
for everybody.
However, I'm curious as to what is being planned to avoid code repetition in a varied environment;
for example, how will a plugin interact with the ORM layer if it could be *any* ORM?
A quick glance (maybe I've missed something) through some of the merb plugins shows that
developers take one of two paths:
- pick their favorite ORM, and too bad for the users if it doesn't match
- write code for as many as possible. This is more or less the exact negation of DRY. For a substantial
example of this, see the merbful_authentication plugin (http://merbful-auth.rubyforge.org/svn/trunk/).
Well written, with support for 2 ORMs (one is a stub) *and* 2 testing frameworks.
Not trying to start a holy war, but isn't there *some* better way to do this? API consistency is part of the
goal for Rails 3, so couldn't an API abstracting out some of these differences be created? I realize that
heavy-duty database stuff might need to fallback to a specific ORM, but simple stuff like validations and
callbacks shouldn't require maintaining a multitude of nearly-identical codebases.
So what you’re suggesting is some thin layer on top of different ORMs that abstracts away things that are already similar between them?
Isn’t that, like, an ORM for an ORM?
What you said there – “pick their favorite ORM, and too bad for the users if it doesn’t match” – I think it will stay like this with most plugins. One can’t expect that they can switch to another ORM in their application with all libraries and plugins continuing to work without modifications.
So what you’re suggesting is some thin layer on top of different ORMs that abstracts away things that are already similar between them?
If I remember, that was always the plan for Merb, and is now the plan for Rails.
Isn’t that, like, an ORM for an ORM?
Yes, it does sound ridiculous. It would be much better if we could settle on a single ORM (maybe something with highly pluggable backends, like DataMapper), or if we’d at least have multiple ORMs expose roughly the same API.
But neither of those are really possible, whereas it probably is possible to add an ORM abstraction layer. Not something you’d use in an app, but it does make sense for plugins. After all, there aren’t that many differences in how to use the major ones.
That was part of what inspired my original post; some effort seems to
be moving in that
direction. Add to that ActiveModel's goal of extracting things like
validations and callbacks,
which is similar even though it's mostly looking towards ActiveResource.
There's also a number of projects that have effectively been using
ActiveRecord *as* the
ORM of the ORM; ActiveCouch comes to mind (maps CouchDB calls to AR).
Or... we could wait to see what happens with ActiveORM, which seems to
have been stubbed out in one of wycats's branches
Hopefully some common functionality can be defined, and we can all
work together.
ActiveORM is a rather grandiose name right now, but the intention is
for it to provide a set of hooks which allow other ORMs to expose 'AR
like' behaviour so things like form helpers can work transparently.
Over time this could extend to support other functionality.
So for plugins which just work with 'stuff' they're given. Like 'this
thing is a user that authenticates', then backends can probably be
abstracted and we can probably rely on duck-typing for a big chunk of
it.
But plugins which extend ActiveRecord or DataMapper, I can't see
anything possible there. Unless we simply make both the API and the
implementation identical, in which case why have multiple ORMs?
Variety and experimentation is great, that's what's going to lead to
interesting improvements.
I totally agree - obviously a plugin that's adding to and/or extending ActiveRecord
won't be independent. But it should be possible for a plugin to add most run-of-the mill stuff
(validations, basic associations, callbacks) without worrying about which ORM is under the
hood. That's what I'm hoping will come out of the ActiveModel / ActiveORM efforts.