Полный URL-адрес пути изображения в Rails 3
У меня есть изображение, которое содержит загрузку несущей:
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?
Ответы
Ответ 1
попробуйте path
метод
Image.find(:first).image.path
UPD
request.host + Image.find(:first).image.url
и вы можете обернуть его как помощника, чтобы DRY навсегда
request.protocol + request.host_with_port + Image.find(:first).image.url
Ответ 2
Вы также можете установить настройку конфигурации 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
Ответ 3
Другим простым способом использования является 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"
Ответ 4
Просто ответьте на пол и предоставите помощника:
# 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
Ответ 5
Здесь довольно много ответов. Тем не менее, мне не понравилось ни одно из них, так как все они полагаются на меня, чтобы не забывать явно добавлять порт, протокол и т.д. Я считаю, что это самый элегантный способ сделать это:
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
Yay, теперь у меня есть способ преобразовать URL-адреса образа ресурса в относительные URL-адреса протокола, которые я могу использовать в фрагменте кода, который другие могут захотеть добавить на свой сайт, и они будут работать независимо от протокола, который они используют на своих сайта (при условии, что ваш сайт поддерживает любой протокол).
Ответ 6
Вы не можете ссылаться на объект запроса в электронном письме, так как насчет:
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
Ответ 7
Фактически вы можете легко сделать это с помощью
root_url[0..-2] + image.url
Я согласен, что это выглядит не слишком хорошо, но выполняет свою работу..:)
Ответ 8
Я использовал default_url_options
, потому что request
недоступен в почтовой программе и избегал дублирования имени хоста в config.action_controller.asset_host
, если он еще не указал его.
config.asset_host = ActionDispatch::Http::URL.url_for(ActionMailer::Base.default_url_options)
Ответ 9
Я нашел этот трюк, чтобы избежать двойной косой черты:
URI.join(root_url, image.url)