小编典典

Ruby on Rails:在哪里定义全局常量?

all

我刚刚开始使用我的第一个 Ruby on Rails webapp。我有一堆不同的模型、视图、控制器等等。

我想找到一个好地方来坚持真正全局常量的定义,这适用于我的整个应用程序。特别是,它们既适用于我的模型逻辑,也适用于我的观点中做出的决定。我找不到任何 DRY
的地方来放置这些定义,它们对我的 所有 模型和我的所有视图都可用。

举一个具体的例子,我想要一个常量COLOURS = ['white', 'blue', 'black', 'red', 'green']。这在模型和视图中随处可见。我可以在哪里只在一个地方定义它以便可以访问它?

我试过的:

  • 与它们最相关的 model.rb 文件中的常量类变量,例如@@COLOURS = [...]. 但是我找不到一种理智的方式来定义它,这样我就可以用我的观点来写,Card.COLOURS而不是像Card.first.COLOURS.
  • 模型上的一种方法,类似于def colours ['white',...] end- 同样的问题。
  • application_helper.rb 中的一个方法 - 这是我目前正在做的事情,但助手只能在视图中访问,而不是在模型中
  • 我想我可能在 application.rb 或 environment.rb 中尝试过一些东西,但这些看起来并不正确(而且它们似乎也不起作用)

有没有办法定义任何可以从模型和视图访问的东西?我的意思是,我知道模型和视图应该是分开的,但肯定在某些领域中,有时它们需要引用相同的特定领域知识?


阅读 93

收藏
2022-06-04

共1个答案

小编典典

如果您的模型真的对常量“负责”,那么您应该将它们粘贴在那里。您可以创建类方法来访问它们,而无需创建新的对象实例:

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数组。这可以防止其他代码稍后(无意中)通过添加新元素来修改数组。一旦对象被冻结,就不能再更改它。

2022-06-04