The Base class in Rails

Hi,

One of the things about the Rails code that people tend to frown upon is the Base class. I was wondering if anyone ever considered replacing it with with a class name that reflects the actual function of the class? Maybe we could even use ActiveRecord as a 'base class' for models? Staying backwards compatible for a while – at least for application code – should be possible.

   http://gist.github.com/15813

Manfred

Hi Manfred

One of the things about the Rails code that people tend to frown upon
is the Base class. I was wondering if anyone ever considered replacing

Can you point me in the direction of some discussion of what's wrong
with the "Base class" that people "frown upon"?

Just wondering, since I don't recall a problem off-hand?

One of the things about the Rails code that people tend to frown upon
is the Base class. I was wondering if anyone ever considered replacing

Can you point me in the direction of some discussion of what's wrong
with the "Base class" that people "frown upon"?

I don't know of any articles that talk about this, I've mostly discussed it face-to-face.

And example of a project that changed their API is Datamapper, they went from:

   class Author < DataMapper::Base; end

To

   class Author; include DataMapper::Resource; end

Just wondering, since I don't recall a problem off-hand?

There is no problem in the sense that tests are failing or a feature is broken. It's just weird to have a class with a non-descriptive name.

I get the feeling that the Base class was created because David wanted to create a namespace named ActiveRecord to prevent conflicts but also wanted to have something you could inherit from. ActiveRecord::ActiveRecord is weird, so it ended up being ActiveRecord::Base. I personally think ActiveRecord::Model or just ActiveRecord would have been a better name.

I see a lot of people using this as an idiom in other Ruby libraries and applications because they learn their first Ruby by developing a Rails applications, even though this idiom might not fit their project.

Manfred

It's too major of a change to make imo and there's just too many
tutorials/docs out there that reference Class Model <
ActiveRecord::Base. To me, it makes sense that a model "inherits from"
ActiveRecord::Base because that's where a model gets its methods from.

I always assumed that AR::Base and AC::Base’s name came from the concept of an abstract base class. I think ::Base is a fine name for the top-most superclass in a module, but that might just be a side effect of previous experience.

-Trek

If you renamed ActiveRecord::Base to ActiveRecord::Model, then a model
that inherited from ActiveRecord::Model would get its methods from
ActiveRecord::Model. You could make this completely backwards
compatible too. Just rename ActiveRecord::Base to ActiveRecord::Model
and then:

  ActiveRecord::Base = ActiveRecord::Model

That being said, I'd say that changing to a more accurate name isn't
worth the risk of confusion.

Jeremy

Regarding tutorials/docs – would there really be a problem with doing this, then:

class ActiveRecord
Base = self
end

In other words, ::Base would still work, it’d just be redundant, and probably depricated.

As for the clarity, there’s plenty of indirection anyway. I’d rather have a clear API.

In fact, that is the whole point of Rails, to me – having everything be clear, simple, and easy, so I have less to think about. ::Base is information I don’t need, and don’t care about. It’s not DRY, and it’s pointless.

But I’m also not sure how much it’s worth arguing about.

That breaks code that assumes ActiveRecord is a module and not a
class, which is going to be a lot of code.

Jeremy

That's why such a change should only be introduced in a point release,
which will break a lot of code anyway and this will probably be the easiest
compatibility fix of all of them. So I don't think that's really an argument against it.

I find Base the worst class name ever.
It does not at all communicate it's intention other
than that it's a base class for something.

Eloy

Regarding tutorials/docs -- would there really be a problem with
doing this,
then:

class ActiveRecord
Base = self
end

That breaks code that assumes ActiveRecord is a module and not a
class, which is going to be a lot of code.

That's why such a change should only be introduced in a point release,
which will break a lot of code anyway and this will probably be the
easiest
compatibility fix of all of them. So I don't think that's really an
argument against it.

I find Base the worst class name ever.
It does not at all communicate it's intention other
than that it's a base class for something.

It's the base class for active record models. If you consider the
name outside the context of the module it's in, then yeah, it's shit.
But the same is true of almost every class that's in a module, unless
you do something weird like:

Database::DatabaseConnection

rather than

Database::Connection

Fundamentally though, the name is entrenched in every rails app out
there, and we'd need a reason other than "ick" to go and change it,
even in a 3.0 release.

Regarding tutorials/docs -- would there really be a problem with
doing this,
then:

class ActiveRecord
Base = self
end

That breaks code that assumes ActiveRecord is a module and not a
class, which is going to be a lot of code.

That's why such a change should only be introduced in a point release,
which will break a lot of code anyway and this will probably be the
easiest
compatibility fix of all of them. So I don't think that's really an
argument against it.

I find Base the worst class name ever.
It does not at all communicate it's intention other
than that it's a base class for something.

It's the base class for active record models. If you consider the
name outside the context of the module it's in, then yeah, it's shit.
But the same is true of almost every class that's in a module, unless
you do something weird like:

Database::DatabaseConnection

rather than

Database::Connection

Well the only weird thing here is the same issue as with ActiveRecord::Base.
In other words, name it: Product::DatabaseConnection.

Fundamentally though, the name is entrenched in every rails app out
there, and we'd need a reason other than "ick" to go and change it,
even in a 3.0 release.

Actually in modern Rails apps, don't know about older versions though,
there is no occurrence at all of the string "module ActiveRecord".

Anyways, I don't think discussing these implementation details adds
anything to a possible discussion about the original question.
Because it is indeed, as you say, just an "ick" :slight_smile:

About the original question, I actually think Manfred really wanted to know
if his assumption about why it was named this way by David was correct. [1]
Any ideas on that?

Cheers,
Eloy

[1]: "I get the feeling that the Base class was created because David wanted
to create a namespace named ActiveRecord to prevent conflicts but also
wanted to have something you could inherit from.
ActiveRecord::ActiveRecord is weird, so it ended up being
ActiveRecord::Base. I personally think ActiveRecord::Model or just
ActiveRecord would have been a better name." -- Manfred

About the original question, I actually think Manfred really wanted to
know
if his assumption about why it was named this way by David was
correct. [1]
Any ideas on that?

I have no idea. But back in the dark ages when I did java
programming, that was a common naming pattern. I expect that the
bikesheds were traditionally painted another colour back then :).

Can I just add that, since this is purely a bikeshed discussion, and
there is TONS of code that inherits from ActiveRecord::Base (and
others), there is no reason to repaint everyone's bikeshed red just to
satisfy the few people that have mentioned casually that they don't
really like blue?

I suspect you'd hear quite the uproar breaking such a huge piece of
compatibility. It is the way it is.

On a related note, the "internals" change of Inflector ->
ActiveSupport::Inflector and Dependencies ->
ActiveSupport::Dependencies in Rails 2.1.1 actually broke alot of my
code that was in Rakefiles and other places that was taking advantage
of these very cool Rails modules. For this reason we're stuck on
Rails 2.1.0 until we can lockstep upgrade everything. It's actually a
huge pain in the butt, again for a needless bikeshed change.

"Better" or "prettier" or "more proper" should never trump
"incompatible".

-Nate

Then how would any software ever progress?

I have Windows 95 software that's incompatible with Windows XP. I
still have licenses for OCX controls from VB4 that don't work with
.NET. But this incompatibility is necessary to ensure progress and
refinement of the software products.

I realize the change you mentioned is trivial and probably should have
gone through a "holy crap this is going away phase", but I don't think
your point about it NEVER trumping incompatibility holds a lot of
water.

</thread_jack>

--Jeremy

It’s even more purely a bikeshed discussion than you mention, as there’s no particular reason this would break code that inherits from ActiveRecord::Base. Again:

class ActiveRecord
Base = self

end

Problem solved. If we want to purge ::Base, depricate it and remove it several versions later.

The bigger problem is code which naively does this:

module ActiveRecord

end

And I’ve found this to be a better practice anyway, especially with Rails autoloading:

ActiveRecord.module_eval do

end

Which would work just fine, whether it’s a module or a class.

In other words: This isn’t likely to break much code. It is very much a question of taste. No one’s suggesting that we rebuild the bikeshed, or change the locks – only painting it a different color.

Going back to the origin of the thread, I've always thought there's a
missing ApplicationModel in Rails and in fact wrote a patch some time
ago:

   http://dev.rubyonrails.org/ticket/10832

The only detail that I am doubting about is that Rails docs inherit
from AR::Base in their example code and so Rails docs would change
that to ApplicationModel. On the other hand AR can be used outside
Rails where ApplicationModel would make no sense in general, and the
docs are the same ones.

Other than that, I'd personally like to have ApplicationModel someday.

@Jeremy: You're somewhat twisting my words, I'm not saying software
should never change. Just that this is a purely cosmetic change. It
doesn't improve things. So there's no real justification for it, other
than "some people would prefer it a different way." There's no reason
to break things that ain't broke.

@David: Lots of plugins mixin to ActiveRecord::Base, or override
methods. Are you going to volunteer to help all those maintainers fix
them? And add nasty checks everywhere to see if Base is defined; else
use the new "better" name?

Now, Xavier mentions an interesting option that may satisfy both
camps. Create an ApplicationModel like ApplicationController. There, a
place for application-specific overrides (rather than environment.rb),
and it doesn't have that "Base" name that apparently bothers a few
people.

Rails is mature enough already, and depended upon enough already that
renaming classes just for the sake of a "better name" should be
completely out of the question. Giving an impression of instability is
not something Rails needs. Just the opposite; Rails still needs to
continue workingl at getting a reputation for being "rock solid" (to
which great strides are being made with the new threading stuff, etc).

-Nate

@Jeremy: You’re somewhat twisting my words, I’m not saying software

should never change. Just that this is a purely cosmetic change.

Cosmetic changes are actually largely why I would use Rails in the first place, I think – and why, when I use Sequel::Model instead of ActiveRecord, I still end up using has_many and belongs_to, rather than one_to_many or associate.

Semantics are important. Syntactic sugar (or vinegar) is important.

@David: Lots of plugins mixin to ActiveRecord::Base, or override

methods. Are you going to volunteer to help all those maintainers fix

them? And add nasty checks everywhere to see if Base is defined; else

use the new “better” name?

Those “nasty” checks could be on Rails.version.

And for the third time now, those plugins would continue to work. ActiveRecord::Base would be exactly the same as ActiveRecord, until a major breaking change (Rails 3?).

Now, Xavier mentions an interesting option that may satisfy both

camps. Create an ApplicationModel like ApplicationController.

Yes, that would satisfy me.

Not that I was particularly passionate about this in the first place. I just wanted to demonstrate that this could be a purely cosmetic change, with little or no impact on compatibility.

Since I actually don’t care, I guess I’m just making noise. I’ll stop.

I still like Base both as a name for what the thing is, it's the base
class of Active Record, and for its reusability across different
frameworks, like ActionController::Base, ActiveResource::Base, etc. I
see no gain in changing it nor do I think any of the proposed
alternative names are better (i.e. Resource or Model).

But we've ApplicationController < AC::Base to put common stuff. Modulo
de impedance in the docs I explained, don't you think ApplicationModel
< AR::Base makes sense for the same purpose in Rails?