我刚刚开始使用我的第一个 Ruby on Rails webapp。我有一堆不同的模型、视图、控制器等等。
我想找到一个好地方来坚持真正全局常量的定义,这适用于我的整个应用程序。特别是,它们既适用于我的模型逻辑,也适用于我的观点中做出的决定。我找不到任何 DRY 的地方来放置这些定义,它们对我的 所有 模型和我的所有视图都可用。
举一个具体的例子,我想要一个常量COLOURS = ['white', 'blue', 'black', 'red', 'green']。这在模型和视图中随处可见。我可以在哪里只在一个地方定义它以便可以访问它?
COLOURS = ['white', 'blue', 'black', 'red', 'green']
我试过的:
@@COLOURS = [...]
Card.COLOURS
Card.first.COLOURS
def colours ['white',...] end
有没有办法定义任何可以从模型和视图访问的东西?我的意思是,我知道模型和视图应该是分开的,但肯定在某些领域中,有时它们需要引用相同的特定领域知识?
如果您的模型真的对常量“负责”,那么您应该将它们粘贴在那里。您可以创建类方法来访问它们,而无需创建新的对象实例:
class Card < ActiveRecord::Base def self.colours ['white', 'blue'] end end # accessible like this Card.colours
或者,您可以创建类变量和访问器。然而,这是不鼓励的,因为类变量在继承和多线程环境中可能会令人惊讶。
class Card < ActiveRecord::Base @@colours = ['white', 'blue'].freeze cattr_reader :colours end # accessible the same as above Card.colours
如果需要,上面的两个选项允许您在每次调用访问器方法时更改返回的数组。如果你有一个真正不变的常量,你也可以在模型类上定义它:
class Card < ActiveRecord::Base COLOURS = ['white', 'blue'].freeze end # accessible as Card::COLOURS
您还可以在初始化程序中创建可从任何地方访问的全局常量,如下例所示。这可能是最好的地方,如果你的颜色真的是全局的并且在多个模型上下文中使用。
# put this into config/initializers/my_constants.rb COLOURS = ['white', 'blue'].freeze # accessible as a top-level constant this time COLOURS
注意:当我们在上面定义常量时,往往我们想要freeze数组。这可以防止其他代码稍后(无意中)通过添加新元素来修改数组。一旦对象被冻结,就不能再更改它。
freeze