如何在rails4中为default_url使用摘要感知资产?

jem*_*ons 9 helper carrierwave asset-pipeline ruby-on-rails-4

在Rails 3,作为使用资产从管道default_urlcarrierwave的上传,你不喜欢的东西如下:

class MyUploader
  # Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility:
  include Sprockets::Helpers::RailsHelper
  include Sprockets::Helpers::IsolatedHelper

  def default_url
    # For Rails 3.1+ asset pipeline compatibility:
    asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
  end
end
Run Code Online (Sandbox Code Playgroud)

在导轨4中,管道被抽象到sprockets-rails gem/railtie中,因此上面的内容将为您提供:

未初始化的常量链轮::助手

看看sprockets-rails gem,替换助手似乎就是这样Sprockets::Rails::Helper.但是包含这个模块,asset_path("fallback/default.png")返回,简单地说:

# wrong:
"/fallback/default.png"
Run Code Online (Sandbox Code Playgroud)

不是我期望的资产和摘要感知网址:

"/assets/fallback/default-b3beee1588afe2ae582c64888cd007db.png"
Run Code Online (Sandbox Code Playgroud)

如何asset_path在视图外获得正确的行为?

jem*_*ons 19

TL; DR:

不要include什么.使用帮助程序代理,如下所示:

def default_url
  ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
end
Run Code Online (Sandbox Code Playgroud)

血腥细节:

Sprockets::Rails::Helper利用链轮清单来正确定位和消化资产.一旦它被抽象成为rails 4的gem,这个清单开始由铁路设置.因此,简单地include将模块的方法引入到我们的类中并不足以将该清单拉入其中,并且asset_path(错误地)相应地表现出来.

值得庆幸的是,有一个经常被忽视的 ActionController::Base.helpers类方法:

提供从视图外部访问帮助程序方法的代理.

就像文档说的那样,它充当了一个帮助代理,并且可能从一开始就应该用于此目的(包括辅助模块到你的命名空间)冒着用未使用的方法污染你的类并可能覆盖东西的风险,所以使用代理是更好的选择).

可能还有一些相当的Sprockets::Helpers::IsolatedHelper黑客攻击力足以提供Sprockets::Rails::Helper完成工作所需的东西.但代理是,恕我直言,一个更优雅的解决方案.所以我已经停止了搜索.