Rails 3中的图像path的完整url

我有一个图像,其中包含carrierwave上传:

Image.find(:first).image.url #=> "/uploads/image/4d90/display_foo.jpg" 

在我看来,我想find这个绝对的url。 追加root_url结果为double /

 root_url + image.url #=> http://localhost:3000//uploads/image/4d90/display_foo.jpg 

我不能使用url_for (我知道),因为它可以允许传递path选项列表来标识资源和:only_path选项。 由于我没有可以通过“controller”+“action”识别的资源,所以我不能使用:only_path选项。

 url_for(image.url, :only_path => true) #=> wrong amount of parameters, 2 for 1 

在Rails3中创build完整path的path最干净和最好的方法是什么?

尝试path方法

 Image.find(:first).image.path 

UPD

 request.host + Image.find(:first).image.url 

你可以把它作为帮手包装起来,永远干掉它

 request.protocol + request.host_with_port + Image.find(:first).image.url 

您也可以像这样设置CarrierWave的asset_hostconfiguration设置:

 # config/initializers/carrierwave.rb CarrierWave.configure do |config| config.storage = :file config.asset_host = ActionController::Base.asset_host end 

这个^告诉CarrierWave使用你的应用程序的config.action_controller.asset_host设置,它可以在你的config/envrionments/[environment].rb文件中定义。 在这里看到更多的信息。

或者明确地设置它:

  config.asset_host = 'http://example.com' 

重新启动你的应用程序,你很好去 – 没有需要帮手的方法。

*我正在使用Rails 3.2和CarrierWave 0.7.1

另一个简单的方法是使用URI.parse,在你的情况下

 require 'uri' (URI.parse(root_url) + image.url).to_s 

和一些例子:

 1.9.2p320 :001 > require 'uri' => true 1.9.2p320 :002 > a = "http://asdf.com/hello" => "http://asdf.com/hello" 1.9.2p320 :003 > b = "/world/hello" => "/world/hello" 1.9.2p320 :004 > c = "world" => "world" 1.9.2p320 :005 > d = "http://asdf.com/ccc/bbb" => "http://asdf.com/ccc/bbb" 1.9.2p320 :006 > e = "http://newurl.com" => "http://newurl.com" 1.9.2p320 :007 > (URI.parse(a)+b).to_s => "http://asdf.com/world/hello" 1.9.2p320 :008 > (URI.parse(a)+c).to_s => "http://asdf.com/world" 1.9.2p320 :009 > (URI.parse(a)+d).to_s => "http://asdf.com/ccc/bbb" 1.9.2p320 :010 > (URI.parse(a)+e).to_s => "http://newurl.com" 

只要回答问题并提供帮手:

 # Use with the same arguments as image_tag. Returns the same, except including # a full path in the src URL. Useful for templates that will be rendered into # emails etc. def absolute_image_tag(*args) raw(image_tag(*args).sub /src="(.*?)"/, "src=\"#{request.protocol}#{request.host_with_port}" + '\1"') end 

这里有相当多的答案。 然而,我不喜欢他们中的任何一个,因为他们都依靠我记得明确添加端口,协议等。我觉得这是做这件事最优雅的方式:

 full_url = URI( root_url ) full_url.path = Image.first.image.url # Or maybe you want a link to some asset, like I did: # full_url.path = image_path("whatevar.jpg") full_url.to_s 

而最好的事情是,我们可以很容易地改变一件事,不pipe你可能做什么,总是以同样的方式去做。 说如果你想放弃协议,并使用“协议相对URL” ,则在最终转换为string之前执行此操作。

 full_url.scheme = nil 

是的,现在我有一种方法来将我的资源图片url转换为协议相关url,我可以使用其他人可能希望在其网站上添加的代码段,而且无论他们在网站上使用何种协议您的网站支持任一协议)。

你不能在电子邮件中引用请求对象,那怎么样:

 def image_url(*args) raw(image_tag(*args).sub /src="(.*?)"/, "src=\"//#{ActionMailer::Base.default_url_options[:protocol]}#{ActionMailer::Base.default_url_options[:host]}" + '\1"') end 

你其实可以很容易地完成

 root_url[0..-2] + image.url 

我同意它看起来不太好,但完成了工作.. 🙂

我使用了default_url_options ,因为request在邮件程序中不可用,并且避免在config.action_controller.asset_host复制主机名,如果以前没有指定的话。

 config.asset_host = ActionDispatch::Http::URL.url_for(ActionMailer::Base.default_url_options) 

我发现这个技巧来避免双斜杠:

 URI.join(root_url, image.url)