In rails 3, to use an asset from the pipeline as the default_url
in carrierwave's uploader, you did something like the following:
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
In rails 4, the pipeline has been abstracted into the sprockets-rails gem/railtie, so the above will give you:
uninitialized constant Sprockets::Helpers
Looking at the sprockets-rails gem, the replacement helper would seem to be Sprockets::Rails::Helper
. But with this module included, asset_path("fallback/default.png")
returns, simply:
# wrong:
"/fallback/default.png"
not the asset- and digest-aware URL that I expect:
"/assets/fallback/default-b3beee1588afe2ae582c64888cd007db.png"
How can I get the correct asset_path
behavior outside of a view?
Don't include
anything. Use the helper proxy instead, like this:
def default_url
ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
end
Sprockets::Rails::Helper
makes use of a sprockets manifest to properly locate and digest assets. Once it got abstracted into a gem for rails 4, this manifest started getting set by the railtie. So simply include
-ing the module's methods into our class wasn't enough to pull that manifest in, and asset_path
(mis)behaved accordingly.
Thankfully, there is the oft-overlooked ActionController::Base.helpers
class method:
Provides a proxy to access helpers methods from outside the view.
Like the docs say, it acts as a helper proxy and is probably what should have been used for this purpose from the begining (including helper modules into your namespace runs the risk of polluting your class with unused methods and potentially overwriting stuff, so using the proxy is the better alternative).
There might yet be some equivalent of Sprockets::Helpers::IsolatedHelper
that hacks enough together to give Sprockets::Rails::Helper
what it needs to get the job done. But the proxy is, IMHO, a much more elegant solution. So I've stopped searching.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With