ruby on rails - URL completa para una ruta de imagen en Rails 3
routes in ruby on rails (9)
Tengo una imagen, que contiene cargas de carrierwave:
Image.find(:first).image.url #=> "/uploads/image/4d90/display_foo.jpg"
En mi opinión, quiero encontrar la URL absoluta para esto. Agregar los resultados de root_url en un doble /
.
root_url + image.url #=> http://localhost:3000//uploads/image/4d90/display_foo.jpg
No puedo usar url_for (que yo sepa), porque eso permite pasar una ruta, o una lista de opciones para identificar el recurso y la opción :only_path
. Como no tengo un recurso que pueda identificarse mediante "controlador" + "acción", no puedo usar la opción :only_path
.
url_for(image.url, :only_path => true) #=> wrong amount of parameters, 2 for 1
¿Cuál sería la forma más limpia y mejor para crear una ruta en una URL completa en Rails3?
Aquí hay muchas respuestas. Sin embargo, no me gustó ninguno de ellos, ya que todos confían en mí para recordar agregar explícitamente el puerto, el protocolo, etc. Considero que esta es la forma más elegante de hacerlo:
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
Y lo mejor de todo es que podemos cambiar fácilmente una sola cosa y no importa qué cosa sea, siempre lo haces de la misma manera. Digamos que si desea eliminar el protocolo y usar la URL relativa al protocolo , hágalo antes de la conversión final a la cadena.
full_url.scheme = nil
Sí, ahora tengo una forma de convertir mis urls de imágenes de activos a urls relativas al protocolo que puedo usar en un fragmento de código que otros pueden querer agregar en su sitio y funcionarán independientemente del protocolo que usen en su sitio (proporcionando que su sitio admite cualquiera de los protocolos).
De hecho, puedes lograr esto fácilmente haciendo
root_url[0..-2] + image.url
Estoy de acuerdo en que no se ve muy bien, pero hace el trabajo ... :)
Encontré este truco para evitar doble barra:
URI.join(root_url, image.url)
No puede hacer referencia al objeto de solicitud en un correo electrónico, entonces qué tal:
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
Otro método simple para usar es URI.parse, en su caso sería
require ''uri''
(URI.parse(root_url) + image.url).to_s
y algunos ejemplos:
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"
Simplemente tomando la respuesta del piso y proporcionando el ayudante:
# 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
También puede establecer la configuración asset_host de asset_host
esta manera:
# config/initializers/carrierwave.rb
CarrierWave.configure do |config|
config.storage = :file
config.asset_host = ActionController::Base.asset_host
end
Esto ^ le dice a CarrierWave que use la configuración config.action_controller.asset_host
su aplicación, que se puede definir en uno de sus config/envrionments/[environment].rb
. Mira aquí para más información.
O establézcalo explícitamente:
config.asset_host = ''http://example.com''
Reinicie su aplicación, y ya está listo, no se requieren métodos auxiliares.
* Estoy usando Rails 3.2 y CarrierWave 0.7.1
probar el método de path
Image.find(:first).image.path
UPD
request.host + Image.find(:first).image.url
y puedes envolverlo como ayudante para SECARLO para siempre
request.protocol + request.host_with_port + Image.find(:first).image.url
default_url_options
, porque la request
no está disponible en el programa de correo y evité duplicar el nombre de host en config.action_controller.asset_host
si no lo he especificado antes.
config.asset_host = ActionDispatch::Http::URL.url_for(ActionMailer::Base.default_url_options)