application.rb -> application_controller.rb

The special-case nature of 'application.rb' is a bit of a smell, and judging by the torrent of +1 votes on this ticket, there are a lot of people who feel that way.

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

So, if we want to ship something like this in 2.1 we should make sure it's going to work well. So in addition to renaming the file in newly generated applications, we'll need to have a strategy for people upgrading from earlier versions.

Ideally rake rails:update would be able to warn the user that the file needs to be renamed, if not do the rename itself. If possible it'd be nice to support both names for a while in trunk to avoid any surprises for people running on edge[1].

Will this change enable any new 'stuff' that at present you can't do? Referencing controllers from production.rb being the obvious case.

Finally, as we'd no longer be preloading ApplicationController, is there anything which might be relying on this?

I'm definitely keen on fixing it up, I'm just worried that a torrent of empty +1s may swamp any back-and-forth about the risks and benefits to making the change.

[1] I think you're crazy to be running on edge right now, but some people like it :slight_smile:

The special-case nature of 'application.rb' is a bit of a smell, and judging by the torrent of +1 votes on this ticket, there are a lot of people who feel that way.

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

I still find it confusing that the class ApplicationController resides in a file called application.rb, not following the class/file naming convention used elsewhere.

But I also find it confusing that it's called ApplicationController to begin with, given that it doesn't expose any actions and I never route to it. It's simply a base class for application-wide functionality. So why not call it Application?

Controller superclasses don't have to use the Controller prefix, as evident by ApplicationController::Base.

Assaf -- http://labnotes.org

I would love to hear any possible disadvantages. This has always something that has bugged me, just never got around to ticketing it.

sounds like a good move in general, but i don't know if it's worth it without really considering the goal of the original ApplicationController and how it basically falls down on the job. let me explain: it's bothered me to no end that rails doesn't really support any sort of centralized view of what the hell and application does, especially for a developer inheriting a project. application.rb is a nice spot not only for sharing behavior across controllers, but also for monkey patching junk in in a way that people are likely to notice it. however, we have no such equivalent for models or the app as a whole - only views share something similar. lately i've been doing this

   app/api.rb

and putting all my config, all my thick model stuff, and all the high level stuff for my app that people should be able to use. i won't go into the details other than to point out i think we sorely need something like

   App.google_ad_client 'pub-1234'

   App.create_user email, password

   App.model do      default 'rating' => 42    end

so a central set of base classes for models, controllers, views and also config. the reason i mention this is that 'application.rb' is a *perfect* name for such a file. of course i can't use it so i use api.rb, site.rb, or sometimes app.rb. none of them feels right however. so my basic concern is not so much that 'application.rb' is named poorly, rather it is that it does very little to aid adding a central entry point for developers which, imho, something named that way should.

seems worth considering since another location for application.rb with different roles, including that if setting up a base controller, might suggest an all together different migration strategy.

kind regards.

a @ http://drawohara.com/

In my view ApplicationController is just about controllers, inheriting filters, common utilities, etc. I believe any other application-wide stuff like monkey-patching had a place in Rails pre-2, which was the bottom of environment.rb, and now the initializers.

If you are new to a project one of the first things you need to do is to open environment.rb/initializers and be aware of custom stuff. I had considered reopening String somewhere under app to be a dubious practice in the sense that the place is not as conventional as those are.

Configuration stuff went somewhere in environment.rb or in some .yml under config. If environment.rb got too big you factored something out in some file, and require it from environment.rb. But the single entry point to see custom extensions and global stuff was still that one, you still saw some require "add_unary_minus_to_nilclass.rb" to follow.

In general I think we do have a place for that kind of stuff, so I am +1 on the renaming because of the naming coherence.

I agree an abstract ApplicationModel < AR::Base is missing to complete a coherent setup. I have not needed such a class very often in practice, but I think I've reopened AR::Base a couple of times to do what you normally would do via inheritance. In those cases I didn't introduce an abstract root model to invest the minimum effort and be able to leverage the original generators.

-- fxn

In my view ApplicationController is just about controllers, inheriting filters, common utilities, etc. I believe any other application-wide stuff like monkey-patching had a place in Rails pre-2, which was the bottom of environment.rb, and now the initializers.

but this is a very painful place to do it - you need to get it right the *first time* - either that or restart you webserver each time : it's not reloaded like the rest of your 'application' is. same goes for 'lib' of course. application code should be reloaded in development like, er, the application :wink:

If you are new to a project one of the first things you need to do is to open environment.rb/initializers and be aware of custom stuff. I had considered reopening String somewhere under app to be a dubious practice in the sense that the place is not as conventional as those are.

yes that's true of course. none would would be as clear as

module Application    module RubyExt      module String        def ellipsis() ... end      end

     RubyExt.constants.each{|c| Object.const_get(c).send :include, const_get(c)}    end end

as i have in some of my projects now though. hacking built-ins should absolutely have a single well known best-pratise place in rails considering that the average application is going to have about 500 files loaded.

Configuration stuff went somewhere in environment.rb or in some .yml under config. If environment.rb got too big you factored something out in some file, and require it from environment.rb. But the single entry point to see custom extensions and global stuff was still that one, you still saw some require "add_unary_minus_to_nilclass.rb" to follow.

yes i've done both. again this is far less desirable to something like

   Application.config.google_ad_client

which is to say there is not a namespace - no best practice - it's just expected that people will litter the global namespace with a bunch of stuff you should trace with grep.

In general I think we do have a place for that kind of stuff, so I am +1 on the renaming because of the naming coherence.

me too - just to be clear my point is to consider the bigger picture as an aid to determining how it might best be done

I agree an abstract ApplicationModel < AR::Base is missing to complete a coherent setup. I have not needed such a class very often in practice, but I think I've reopened AR::Base a couple of times to do what you normally would do via inheritance. In those cases I didn't introduce an abstract root model to invest the minimum effort and be able to leverage the original generators.

a great example is

   ApplicationModel < ActiveRecord::Base      before_save do |record|        record.updated_by = ApplicationController.current if          record.respond_to? 'updated_at'      end    end

which, of course, can be done in rails but only with a series of monkey patches. do you really think it's clear to people a) how to do this, b) where it should go? i really don't but maybe i'm just not rails-y enough.

anyhow - i don't want to derail the original thread but thought it worth mentioning that a real refactoring of application.rb might end up with that file returning under a different guise and this suggests a few alternate methods to lessen peoples pain and support new unified application classes. for instance assume that any ApplicationController would also be defined in any such new unified scheme, then rails could simply

   %w[ app/controllers/application.rb app/application.rb ].each do |basename>      pathname = File.join RAILS_ROOT, basename      load pathname if test ?s, basename    end

and now it's setup to provide a new style application.rb file and support the old style one - or both.

i'll duck out now since i think my point has been made.

cheers.

a @ http://codeforpeople.com/

a great example is

  ApplicationModel < ActiveRecord::Base     before_save do |record|       record.updated_by = ApplicationController.current if         record.respond_to? 'updated_at'     end   end

Yes, custom macros would go there as well... it has use cases.

which, of course, can be done in rails but only with a series of monkey patches. do you really think it's clear to people a) how to do this, b) where it should go? i really don't but maybe i'm just not rails-y enough.

I think it would be expected to emulate what's done with ApplicationController. That is, the rails generator would write

   app/models/application_model.rb

with something like

   class ApplicationModel < ActiveRecord::Base      # Stuff common to your models comes here.    end

and the model generator would output something like this

   class User < ApplicationModel    end

Active Record would understand ApplicationModel is abstract as a hard-coded builtin assumption.

-- fxn

yep that's a start. i'd personally push harder though - i would love to run rdoc over my rails app and see sections for

   Application::Controller

   Application::Model

   Application::View

   Application::Config

   Application::RubyExt

etc. the rails structure is currently a tree without a root - without a single entry point or logical 'top' - add to that the beautiful and dangerous fact that you can hack any class anywhere and you end up with a mess. the current structure organizes mvc, but not applications imho, either logically or physically. helpers might be the only exception, but of course they are simply procedural in nature having no state to leverage and not a wide enough domain.

kind regards

a @ http://codeforpeople.com/

I would prefer it to follow the layout of all the other controllers. For example if you tell someone to "go into the blogs controller" they will look for a file called "blogs_controller" in the app/controllers directory instinctively. If you tell someone to "look for the application controller", they'll instinctively look for application_controller.rb, and then realise it's actually application.rb.

So what if a few thousand websites have to rename ONE file. It's no worse than the changes within files Rails 2.0 caused (i.e. routing & session)

I think Assaf hit the nail on the head. Doing this would keep the controller namespace completely clean (ie. someone could have ApplicationController if they want, even though that would probably be a bad idea). Granted, it might be too much pain since every single controller file would then have to change. Maybe Rails has matured to the point where this kind of fix is simply too painful relative to the benefit?

My feelings exactly. That was my point to post +1 to the ticket. I really fail to see the benefits of this change. application.rb used to be called abstract_controller.rb - so we've already been on that road before.

My feelings exactly. That was my point to post +1 to the ticket. I really fail to see the benefits of this change. application.rb used to be called abstract_controller.rb - so we've already been on that road before.

Well, what are the other benefits of having a consistenly named parent controller. Consistency is great, but are there features that are easier with this?

For example, are there any changes for plugin authors? Does this make *something* they do any easier?

> My feelings exactly. That was my point to post +1 to the ticket. I > really fail to see the benefits of this change. application.rb used to > be called abstract_controller.rb - so we've already been on that road > before.

Well, what are the other benefits of having a consistenly named parent controller. Consistency is great, but are there features that are easier with this?

I think for a framework, consistency is a goal in itself, it's one key feature developers look for in a framework. For one, Application is not a controller, since no actions are directed at it, merely removing that confusion is a benefit.

Ruby allows you to alias classes (ApplicationController = Application), so it will be interesting to do a backward compatible switch and survey how many plugins can handle it.

Assaf

This actually would make authoring plugins that "monkeypatch" application controllers easier, yes.

Right now one has to jump through hoops to do that (and, above all, know which ones and how).

"monkeypatch" in quotes as this is a recommended (and successfull) practice for quite some apps out there.

So, yes, there's a real benefit.

A little correction. I'm the "-1" guy. "+" was a typo :slight_smile:

Would you mind to elaborate? I don't understand what you mean, but I'm curious.

Michael

You can't alter an app controller class during plugin load stage like you can, e.g., alter a model class because Application hasn't loaded yet at this stage and autoloading will choke because ApplicationController can't be found automatically (due to the file naming convention breakage application.rb).

The "right" hoop to jump through might be to just require application.rb manually from the plugin. A "wrong" hoop might be to postpone controller class patching to e.g. config.to_prepare or something (which seems to work on many setups but miserably break on some due to class reloading issues).

E.g. in Mephistoland there are lots of examples of situations where one wants to add a certain feature through a plugin.

A different path around this issue (rather than renaming application.rb) could be to load Application before the plugin loading stage by default.

Did that answer your question?

and +2 from me.

a @ http://codeforpeople.com/

Could you explain on that part ?

Btw, I like the idea of renaming it to Application instead of ApplicationController, in case we *must* change it.

Application is too generic in my opinion. That is a file related to controllers, not to the application as a whole.

We have application_helper.rb, and I am working on application_model.rb as per some mails in the middle of the thread. I think application_controller.rb is a natural change.

The prefix "Application" would convey a sense of root (abstract) class per layer.

-- fxn