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.

   15813’s gists · GitHub

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?