我如何重构 Rail 的 ApplicationController,并将常量设置为 ActiveRecord 结果?
我正在开发一个 Rails 2.1 项目,该项目具有类似于以下内容的 ApplicationController:
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
我无法运行测试,因为在我的测试环境中,当尝试定义 ADMIN_ROLES 时,我会收到一条错误消息,指出 THIS_SITE 为 nil。我通过执行以下操作解决了该问题:
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
和 ApplicationController::ADMIN_ROLES
在整个应用程序的视图、控制器和模型中使用。我觉得这一切都是错误和肮脏的。我认为这是错误的/肮脏的吗?如果不是,如何重构?
谢谢。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
测试模式下的问题是,即使在填充测试数据库之前,ApplicationController 类也会被加载。虽然使用常量本身没有问题;定义类方法将加载从数据库时刻移至未来,并让您运行测试。
但是,我确实认为您的代码中的“@@this_site”可能应该是“@this_site”。
从系统架构师的角度来看,this_site 和 admin_roles 看起来都像每个应用程序的设置,应该从控制器部分移出。定义应用程序范围设置的好地方是在 config/initializers 下面或在您的环境中。rb
BTW:Rails 2.1 是不是有点过时了?
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?