it-swarm.com.de

Vollständige URL für einen Bildpfad in Rails 3

Ich habe ein Bild, das Carrierwave-Uploads enthält: 

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

Aus meiner Sicht möchte ich die absolute URL dafür finden. Das Anhängen von root_url führt zu einem doppelten /.

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

Ich kann url_for (das ich kenne) nicht verwenden, da entweder die Weitergabe eines Pfads, oder eine Liste von Optionen zur Identifizierung der Ressource und der Option :only_path zulässt. Da ich keine Ressource habe, die über "Controller" + "Aktion" identifiziert werden kann, kann ich die :only_path-Option nicht verwenden. 

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

Was wäre der sauberste und beste Weg, um in Rails3 einen Pfad zu einer vollständigen URL zu erstellen?

35
berkes

versuchen Sie die path-Methode

Image.find(:first).image.path

UPD

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

und Sie können es als Helfer für DRY für immer einpacken

request.protocol + request.Host_with_port + Image.find(:first).image.url
33
fl00r

Sie können auch die Einstellung asset_Host config von CarrierWave folgendermaßen einstellen:

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

Dies ^ weist CarrierWave an, die Einstellung config.action_controller.asset_Host Ihrer App zu verwenden, die in einer Ihrer config/envrionments/[environment].rb-Dateien definiert werden kann. Siehe hier für weitere Informationen.

Oder explizit setzen:

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

Starten Sie Ihre App neu und schon kann es losgehen - es sind keine Hilfemethoden erforderlich.

* Ich verwende Rails 3.2 und CarrierWave 0.7.1

95
ncherro

Eine andere einfache Methode ist URI.parse, in Ihrem Fall wäre es 

require 'uri'

(URI.parse(root_url) + image.url).to_s

und einige Beispiele:

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" 
10
c2h2

Nehmen Sie einfach die Antwort auf dem Boden und stellen Sie den Helfer zur Verfügung:

# 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
M.G.Palmer

Hier gibt es eine Menge Antworten. Ich mochte keine von ihnen, da sich alle darauf verlassen, dass ich den Port, das Protokoll usw. explizit hinzufüge. Ich finde, das ist die eleganteste Art, dies zu tun:

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

Und das Beste daran ist, dass wir einfach nur eine Sache ändern können, und egal, was auch immer Sie tun, Sie tun es immer auf die gleiche Weise. Sagen Sie, wenn Sie das Protokoll löschen und die The Protocol-relative URL verwenden möchten, tun Sie dies vor der endgültigen Konvertierung in eine Zeichenfolge.

full_url.scheme = nil

Ja, jetzt habe ich eine Möglichkeit, meine Asset-Image-URLs in Protokoll-Relative-URLs umzuwandeln, die ich für ein Code-Snippet verwenden kann, das andere möglicherweise auf ihrer Site hinzufügen möchten. Sie funktionieren unabhängig von dem auf ihrer Site verwendeten Protokoll (sofern verfügbar) dass Ihre Site beide Protokolle unterstützt).

2
Timo

Ich habe default_url_options verwendet, weil request im Mailer nicht verfügbar ist und es vermieden wurde, den Hostnamen in config.action_controller.asset_Host zu duplizieren, wenn er noch nicht angegeben wurde.

config.asset_Host = ActionDispatch::Http::URL.url_for(ActionMailer::Base.default_url_options)
2
Eugene

Sie können sich nicht auf das Anforderungsobjekt in einer E-Mail beziehen.

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
1
Luke W

Sie können dies einfach mit erledigen

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

Ich stimme zu, dass es nicht so gut aussieht, aber die Arbeit erledigt ist .. :)

1
Alfie

Ich habe diesen Trick gefunden, um doppelten Schrägstrich zu vermeiden:

URI.join(root_url, image.url)
0
hlcs