3

我一直致力于从 2.3.11 升级到 Rails 3.1。要清除的主要障碍之一是向资产管道的转换。在这个过程中,我决定将我的 css 转换为 sass (scss)。在 rails 3.1 中,通过管道交付的所有资产都会在生产中收到附加到文件名的哈希。因此,我的 css 中引用的所有图像现在都需要使用 sass 中的 image-path 或 image-url 助手。问题是,即使我在 environment.rb 文件中设置了 ENV['RAILS_RELATIVE_URL_ROOT'],sass 资产帮助程序也无法包含 relative_url_root。

为了清楚起见,为了在 rails 3.1 中添加 relative_url_root,我在 environment.rb 文件中添加了以下行:

ENV['RAILS_RELATIVE_URL_ROOT'] = '/foo'

并将以下行添加到我的虚拟主机:

RailsBaseURI /foo

这种策略似乎适用于所有链接等。只是 sass 中的资产助手似乎无法正常工作。任何想法,将不胜感激。

4

1 回答 1

3

经过一番挖掘,我发现了问题所在。问题出在 Rails 中,特别是 Sprockets::Helpers::RailsHelper::AssetPaths#compute_public_path。Sprockets::Helpers::RailsHelper::AssetPaths 继承自 ActionView::AssetPaths 并覆盖了许多方法。当通过 Sass::Rails::Resolver#public_path 方法调用 sass-rails 的 compute_public_path 时,rails sprocket helper 将承担解析资产的任务。Sprockets::Helpers::RailsHelper::AssetPaths#compute_public_path 遵循超级,即 ActionView::AssetPaths#compute_public_path。在这个方法中有一个has_request的条件吗?在 rewrite_relative_url_root 上,如下所示:

def compute_public_path(source, dir, ext = nil, include_host = true, protocol = nil)
  ...
  source = rewrite_relative_url_root(source, relative_url_root) if has_request?
  ...
end

def relative_url_root
  config = controller.config if controller.respond_to?(:config)
  config ||= config.action_controller if config.action_controller.present?
  config ||= config
  config.relative_url_root
end

如果您查看 rewrite_relative_url_root 的内部结构,它依赖于存在的请求以及从控制器变量派生它以解析相对 url 根的能力。问题是当 sprockets 为 sass 解析这些资产时,它没有控制器存在,因此没有请求。

上面的解决方案对我来说在开发模式下不起作用。这是我现在用来使其工作的解决方案:

module Sass
  module Rails
    module Helpers
      protected
      def public_path(asset, kind)
        resolver = options[:custom][:resolver]
        asset_paths = resolver.context.asset_paths
        path = resolver.public_path(asset, kind.pluralize)
        if !asset_paths.send(:has_request?) && ENV['RAILS_RELATIVE_URL_ROOT']
          path = ENV['RAILS_RELATIVE_URL_ROOT'] + path
        end
        path
      end
    end
  end
end
于 2011-09-10T20:17:11.063 回答