我一直在从2.3.11升级到Rails 3.1。要清除的主要障碍之一是转换为资产管道。在这个过程中,我决定将我的CSS转换为sass(scss)。在rails 3.1中,通过管道传递的所有资产都会在生产中接收附加到文件名的哈希值。因此,我的css中引用的所有图像现在都需要在sass中使用image-path或image-url helpers。问题是,即使我在我的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中的资产助手似乎没有正常工作。任何想法都将不胜感激。
答案 0 :(得分:3)
经过一番挖掘后,我发现了这个问题。问题出在Rails中,特别是Sprockets :: Helpers :: RailsHelper :: AssetPaths#compute_public_path。 Sprockets :: Helpers :: RailsHelper :: AssetPaths继承自ActionView :: AssetPaths并覆盖了许多方法。当通过Sass :: Rails :: Resolver调用compute_public_path #sublic_path方法是sass-rails时,rails sprocket helper接受解析资产的任务。 Sprockets :: Helpers :: RailsHelper :: AssetPaths#compute_public_path遵循super,即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