Полный URL для пути к изображению в Rails 3 - PullRequest
36 голосов
/ 30 марта 2011

У меня есть изображение, которое содержит загрузки несущей:

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

На мой взгляд, я хочу найти абсолютный URL для этого. Добавление root_url приводит к двойному /.

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

Я не могу использовать url_for (о котором я знаю), потому что либо позволяет передавать путь, или список опций для идентификации ресурса и опция :only_path. Так как у меня нет ресурса, который можно было бы идентифицировать через «контроллер» + «действие», я не могу использовать опцию :only_path.

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

Каким будет самый чистый и лучший способ создать путь к полному URL в Rails3?

Ответы [ 9 ]

97 голосов
/ 22 февраля 2013

Вы также можете установить настройку CarrierWave asset_host следующим образом:

# 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

33 голосов
/ 30 марта 2011

попытка 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
11 голосов
/ 09 мая 2012

Другой простой метод для использования - 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" 
5 голосов
/ 18 августа 2011

Просто ответьте на вопрос и предоставьте помощника:

# 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
2 голосов
/ 08 сентября 2015

Я использовал default_url_options, потому что request недоступен в почтовой программе и избегал дублирования имени хоста в config.action_controller.asset_host, если он не был указан ранее.

config.asset_host = ActionDispatch::Http::URL.url_for(ActionMailer::Base.default_url_options)
2 голосов
/ 18 ноября 2013

Здесь довольно много ответов.Однако мне не понравился ни один из них, так как все они полагаются на то, что я не забываю явно добавить порт, протокол и т. Д. Я считаю, что это самый элегантный способ сделать это:

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

И что самое лучшее в этом то, что мы можем легко изменить только одну вещь, и независимо от того, что это может быть, вы всегда делаете это одинаково.Скажем, если вы хотите отбросить протокол и использовать относительный к протоколу URL , сделайте это до окончательного преобразования в строку.

full_url.scheme = nil

Ууу, теперь у меня есть способпреобразование URL-адресов моего ресурса в относительные URL-адреса протокола, которые я могу использовать в фрагменте кода, который другие могут захотеть добавить на свой сайт, и они будут работать независимо от протокола, который они используют на своем сайте (при условии, что ваш сайт поддерживает любой протокол).

1 голос
/ 21 ноября 2017

Я нашел этот трюк, чтобы избежать двойной косой черты:

URI.join(root_url, image.url)
1 голос
/ 03 июля 2015

Вы можете действительно легко сделать это,

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

Я согласен, что это выглядит не слишком хорошо, но выполняет свою работу .. :) 1004 *

1 голос
/ 30 июня 2012

Вы не можете обратиться к объекту запроса в электронном письме, так как насчет:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...