Rails 3.1 SASS 资产助手不包括 RAILS_RELATIVE_URL_ROOT /relative_url_root

发布于 2024-12-04 05:03:26 字数 560 浏览 1 评论 0原文

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

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

ENV['RAILS_RELATIVE_URL_ROOT'] = '/foo'

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

RailsBaseURI /foo

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

I have been working on an upgrade to Rails 3.1 from 2.3.11. One of the main hurdles to clear is the conversion to the asset pipeline. In this process I decided to convert my css to sass (scss). In rails 3.1 all assets delivered through the pipeline receive a hash appended to the filename in production. Because of this, all the images referenced in my css now needed to use the image-path or image-url helpers in sass. The issue is, that even though I have set my ENV['RAILS_RELATIVE_URL_ROOT'] in my environment.rb file sass asset helper fail to include the relative_url_root.

Just for clarity, to add the relative_url_root in rails 3.1, I added the following line to my environment.rb file:

ENV['RAILS_RELATIVE_URL_ROOT'] = '/foo'

and add the following line to my virtual host:

RailsBaseURI /foo

This strategy seems to work fine for all links and such. It is just the asset helpers in sass that don't seem to work properly. Any ideas would be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我做我的改变 2024-12-11 05:03:26

经过一番挖掘后,我发现了这个问题。问题出在 Rails 中,特别是 Sprockets::Helpers::RailsHelper::AssetPaths#compute_public_path。 Sprockets::Helpers::RailsHelper::AssetPaths 继承自 ActionView::AssetPaths 并重写了许多方法。当通过 sass-rails 的 Sass::Rails::Resolver#public_path 方法调用compute_public_path 时,rails sprocket 助手将承担解析资产的任务。 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 根。问题是,当 sprocket 为 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

After a bit of digging around, I have found the issue. The issue is in Rails, specifically Sprockets::Helpers::RailsHelper::AssetPaths#compute_public_path. Sprockets::Helpers::RailsHelper::AssetPaths inherits from ActionView::AssetPaths and overrides a number of methods. When compute_public_path is called through the Sass::Rails::Resolver#public_path method is sass-rails, the rails sprocket helper picks up the task of resolving the asset. Sprockets::Helpers::RailsHelper::AssetPaths#compute_public_path defers to super which is ActionView::AssetPaths#compute_public_path. In this method there is a condition of has_request? on rewrite_relative_url_root as seen below:

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

If you look at the internals of rewrite_relative_url_root it relies on a request to be present and the ability to derive it from the controller variable in order to resolve the relative url root. The issue is that when sprockets resolves these assets for sass it does not have a controller present and therefore no request.

The solution above didn't work in development mode for me. Here is the solution that I am using to make it work for now:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文