I’m working on a Rails 2.1 project that has an ApplicationController similar to the following:
class ApplicationController < ActionController:Base
THIS_SITE = Site.find_by_url('www.example.net')
ADMIN_ROLES = StaffRole.find(:all, :conditions => ["site_id = ? AND name IN (?)", ApplicationController::THIS_SITE.id, 'Administrator'])
end
I was unable to run tests, because in my test environment I would get an error saying THIS_SITE is nil when trying to define ADMIN_ROLES. I fixed the issue by doing the following:
class ApplicationController < ActionController:Base
def self.this_site
@@this_site ||= Site.find_by_url('www.example.net')
end
def self.admin_roles
@admin_roles ||= StaffRole.find(:all, :conditions => ["site_id = ? AND name IN (?)", ApplicationController::this_site.id, 'Administrator'])
end
ApplicationController::THIS_SITE and ApplicationController::ADMIN_ROLES are used throughout the application in views, controllers, and models. I feel that this is all wrong and dirty. Am I wrong thinking that this is wrong/dirty? If not, how can this be refactored?
Thank you.
Your problem in test mode is that the ApplicationController class gets loaded even before the test database is populated. And while there is no problem with using Constants per se; defining class methods moves the loading from the DB moment a bit into the future and let you run your tests.
I do think, however, that “@@this_site” in your code should probably be “@this_site”.
From a sys-architects point of view both this_site and admin_roles look like per-app settings and should be moved out of the controller parts. A good place to define app-wide settings is below config/initializers or in your environment.rb
BTW: Isn’t Rails 2.1 a bit on the old side?