2011-03-30 10 views
34

tengo una imagen, que contiene los archivos subidos carrierwave:URL completa de una imagen de la ruta en Rails 3

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

En mi opinión, quiero encontrar la url absoluta para esto. Adjuntar los resultados 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), debido a que ya sea permite pasar un camino, 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 puede ser la manera más limpia y mejor para crear un camino en una dirección URL completa en Rails3?

Respuesta

33

tratar path método

Image.find(:first).image.path 

UPD

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

y se puede envolver como un ayudante para que se seque siempre

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

que devuelve toda la ruta (sistema). '=>"/home /..../ public/uploads/image/4d90/foo.jpg "' Necesito el URL, no la ruta, para usar en un feed atom. – berkes

+0

oh sí. entonces intente 'request.host + Image.find (: first) .image.url' – fl00r

+1

También no :(' "localhost/uploads/image/4d90/display_foo.jpg" 'Se pierde el: 3000-port (en desarrollo) y http (s): //. – berkes

5

Sólo tomando la respuesta del suelo y proporcionar la 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 
+2

Este ayudante funciona de maravilla dentro de las vistas estándar, pero no puede usarlo en las vistas de Mailer, ya que los remitentes no tienen sentido de una "solicitud", por lo que su ayudante fallará. – Eric

+0

Es cierto. No estoy seguro, pero creo que con Rails 3.1 y la canalización de activos, podría usar el host de activos para armar direcciones URL completas. Con versiones anteriores, creo que uno tendría que codificar el host. –

+0

@ M.G.Palmer ¿esto funcionaría aún, ya que las imágenes cargadas en una onda transportadora residen dentro de la carpeta pública? – lulalala

9

Otro método sencillo de 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" 
+0

¡bastante elegante! –

1

No puede referirse a petición de objetos 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 
91

También puede establecer CarrierWave asset_host escenario como este config:

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

Este^dice CarrierWave utilizar la configuración de tu aplicación config.action_controller.asset_host, que se puede definir en una de sus config/envrionments/[environment].rb archivos. See here para más información.

o configurarlo de forma explícita:

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

reinicia la aplicación, y ya está bueno para ir - no hay métodos auxiliares requeridos.

* Estoy usando Rails 3.2 y 0.7.1 CarrierWave

2

Hay bastante un montón de respuestas aquí. 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.Me parece que este es el modo más elegante de hacer esto:

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 que es lo mejor de todo es que podemos cambiar fácilmente una sola cosa y no importa qué cosa que podría ser que siempre haces de la mismo camino. Digamos que si quisiste soltar el protocolo y usar el The Protocol-relative URL, hazlo antes de la conversión final a la cadena.

full_url.scheme = nil 

Yay, ahora tengo una manera de convertir mis URL de imágenes activo el protocolo URL relativos que puedo usar en un fragmento de código que otros podrían querer añadir en su sitio y que va a trabajar independientemente del protocolo lo usan en su sitio (siempre que su sitio admita cualquiera de los protocolos).

1

En realidad se puede fácilmente hacer esto por

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

estoy de acuerdo que no se ve muy bien, pero hace el trabajo .. :)

2

que utiliza default_url_options, porque no es request disponible en el programa de correo y evitó duplicar el nombre de host en config.action_controller.asset_host si no lo había especificado antes.

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

¡Gracias a un millón! –

0

me encontré con este truco para evitar la doble barra:

URI.join(root_url, image.url) 
Cuestiones relacionadas