你如何告诉Rails /资产管道js.erb依赖于YAML文件?

时间:2013-04-30 18:34:26

标签: ruby-on-rails asset-pipeline yaml erb

我有一个从配置文件加载YAML的js.erb文件。问题是Rails /资产管道将缓存结果,并且永远不会使该缓存失效,即使我更改了YAML文件内容。我可以重启rails服务器甚至重启机器无济于事。到目前为止,我发现的唯一解决方法是做一个“耙资产:干净”。

我想找到一种方法告诉资产管道,当YAML文件发生变化时,需要重新计算我的js.erb。或者,或者告诉它它只能在rails服务器的生命周期中缓存js.erb /确保每次rails服务器启动或重新启动时都会重新生成。

任何建议都将不胜感激。

4 个答案:

答案 0 :(得分:4)

将其添加到config / initializers下的文件中,它将告诉资产管道重新计算每当其中一个支持YAML文件发生更改时加载YAML数据的js.erb文件:

class ConstantsPreprocessor < Sprockets::Processor
  CONSTANTS_ASSET = "support/constants"

  def evaluate(context, locals)
    if (context.logical_path == CONSTANTS_ASSET)
      Constants.load_path.each do |dir|
        dir.each do |yml|
          next unless yml.end_with?".yml"
          context.depend_on("#{dir.path}/#{yml}")
        end
      end
    end

    data
  end
end

Rails.application.assets.register_preprocessor(
    'application/javascript',
    ConstantsPreprocessor)

答案 1 :(得分:1)

如果您正在使用Sprockets 3(例如,使用Rails 5),则可以使用// depends_on。例如,my-constants.js.erb

//= depend_on my_constants.yml
angular
  .module('services.myConstants', [])
  .factory('myConstants', [
    function() {
      return <%= YAML::load_file(Rails.root.join('config/shared/my_constants.yml')).to_json %>;
    }
  ]);

只需确保包含my_constants.yml的目录包含在application.rb的资产路径中:

config.assets.paths.unshift Rails.root.join('config', 'shared').to_s

答案 2 :(得分:0)

我认为你有两个选择:

  1. 禁用资产管道,让Rails随时随地进行编译(对性能不利)

  2. 创建一个守护程序进程,与Rails分开(查找Ruby守护程序)以查找该特定文件中的任何更改并重新编译资产。

  3. 3(额外!)。删除js-YAML依赖项并从对应用程序的AJAX调用中读取YAML的内容。场景是:JS进行AJAX调用,控制器读取YAML文件并将其内容返回给JS文件。因此无需重新编译或监视YAML文件中的更改。

    • 如果选择3,请不要读取控制器中的YAML,创建一个实用程序类来执行它,让控制器让该类读取文件并传递它的内容。

答案 3 :(得分:0)

您可以添加自己的处理器指令,该指令适用于assets目录之外的文件。 = depend_on仅适用于资产文件(https://github.com/rails/sprockets#depend_on

在config / initializers / sprockets.rb中:

Sprockets::DirectiveProcessor.class_eval do
  def process_depend_on_project_file_directive(file)
    path = Rails.root.join(file).to_s
    if File.exists?(path)
      deps = Set.new
      deps << @environment.build_file_digest_uri(path)
      @dependencies.merge(deps)
    end
  end
end

用法:

//= depend_on_project_file "config/setting.yml"

有关详细信息,请参见github上的此评论:https://github.com/rails/sprockets/issues/500#issuecomment-491043517