ruby-on-rails - 在 Rails 初始值设定项中延迟定义常量

标签 ruby-on-rails initializer

我有一个初始化程序,它加载 YML 文件,通过 ERB 解析它,并将生成的哈希值存储在可在应用程序范围内访问的常量中

# config/initializers/links.rb

LINKS = YAML.load(
  ERB.new(File.read(Rails.root.join("config", "links.yml"))).result
)

ERB 的原因是 YML 文件中的某些元素依赖于 URL 帮助程序,需要模板化 -

# config/links.yml
---
footer:
  homepage:
    personal: <%= personal_path %>
    root: <%= root_path %>
    foo: bar
    ....

问题是,当初始化程序运行时,它会失败,因为 Rails 环境尚未初始化(我认为?),因此这些帮助器定义不存在。

为了解决这个问题,我懒惰地读取该文件,因此只有在第一次调用它时才会解析它(大概是在我们加载环境之后)

# config/initializers/links.rb

def links
  unless defined? LINKS
    links = YAML.load(
      ERB.new(File.read(Rails.root.join("config", "links.yml"))).result
    )
    const_set("LINKS", links)
  end

  LINKS
end

但现在我收到错误,因为 const_set 不是已定义的方法。

  1. 在这种情况下如何设置常量?

  2. 此方法是否确保在第一次调用时全局定义常量(即应用程序范围)?如果从 View / Controller /模型/等调用 links() ...我不希望在该类的上下文中设置该常量。

谢谢!

最佳答案

我认为使用它的原因是性能,我认为更好的是创建一个使用 CacheStore 的辅助方法:

module LinksHelper
  def links
    Rails.cache.fetch("links_helper/links", expires_in: 1.hour) do
      YAML.load(
        ERB.new(File.read(Rails.root.join("config", "links.yml"))).result
      )
    end
  end
end

然后您应该仅在必要时包含此帮助程序,并且默认情况下不包含此帮助程序。

关于ruby-on-rails - 在 Rails 初始值设定项中延迟定义常量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33817830/

相关文章:

ios - 在此示例中使用隐式解包可选的意义何在?

methods - 将 Lua 方法定义为初始化

java - Jcabi Github ExceptionInInitializerError

Java super 调整,几个问题

java - 对初始化程序的建议

ruby-on-rails - 如何使用 Sunspot/Solr 在 has_many 关联中进行搜索?

ruby-on-rails - Payola 问题 : undefined method `amount' for nil:NilClass

ruby-on-rails - Ruby on Rails 上的验证码建议

ruby-on-rails - 如何捕获线程中的错误,然后在所有线程完成后重新抛出该错误?

ruby-on-rails - 未定义方法 `synchronize' 对于 nil :NilClass