我对下面的这个文档产生了疑惑:
Computes the full URL to an image asset. This will use image_path internally, so most of their behaviors will be the same. Since image_url is based on asset_url method you can set :host options. If :host options is set, it overwrites global config.action_controller.asset_host setting.
image_url "edit.png", host: "http://stage.example.com" # => http://stage.example.com/edit.png
以上的文档是基于我们要使用 asset pipleline 的。我们先看下源码的调用:
image_url("edit.png", host: "http://stage.example.com") =>
url_to_asset("edit.png", {type: :image, host: "http://stage.example.com")} =>
path_to_asset("edit.png", {type: :image, host: "http://stage.example.com", protocol: :request)}
在path_to_asset
中,参考源码链接https://github.com/rails/rails/blob/3387676efdd03fd6e5b9a70b215ce02cdb1d4ee1/actionview/lib/action_view/helpers/asset_url_helper.rb#L183
我们重点关注计算 path 的那部分:
if source[0] != ?/
if options[:skip_pipeline]
source = public_compute_asset_path(source, options)
else
source = compute_asset_path(source, options)
end
end
因为我们并没有 skip pipeline,所以自然会去执行 else 中的代码 compute_asset_path(source, options)
而compute_asset_path
是被 sprockets-rails 重写了的,源码在这里 (https://github.com/rails/sprockets-rails/blob/857e781998c10e4f429699da1d47ef251844991f/lib/sprockets/rails/helper.rb#L77)
我们可以看到compute_asset_path
会到所有的 asset 中去找这个 source("edit.png"),如果找到了就加上 assets_prefix
File.join(assets_prefix || "/", legacy_debug_path(asset_path, debug))
如果没找到就报错。
所以,我们这里假设“edit.png"是存在项目中的。所以,根据代码的推算我们得到的结果应该是:
"http://stage.example.com/assets/edit-fingerprint.png"
而不是“http://stage.example.com/edit.png”
我在我的一个现有项目 (Rails5) 做了一个实验:
ruby
>> image_url 'approve.jpg', host: "http://stage.example.com"
=> "http://stage.example.com/assets/approve-53ea399216b1c6b2a08f6da00032588a01581600317d94d0445d3514f1dbdba9.jpg"
可以看到,结果和我对代码的推算一致,但是和文档却不同。这个是不是说明文档有问题呢?