J'ai une image, qui contient les téléchargements de carrierwave:
Image.find(:first).image.url #=> "/uploads/image/4d90/display_foo.jpg"
À mon avis, je veux trouver l'URL absolue pour cela. L'ajout de root_url donne un double /
.
root_url + image.url #=> http://localhost:3000//uploads/image/4d90/display_foo.jpg
Je ne peux pas utiliser url_for (à ma connaissance), car soit permet de passer un chemin, ou une liste d'options permettant d'identifier la ressource et l'option :only_path
. Comme je n'ai pas de ressource identifiable via "controller" + "action", je ne peux pas utiliser l'option :only_path
.
url_for(image.url, :only_path => true) #=> wrong amount of parameters, 2 for 1
Quel serait le moyen le plus propre et le meilleur de créer un chemin vers une URL complète dans Rails3?
essayez la méthode path
Image.find(:first).image.path
UPD
request.Host + Image.find(:first).image.url
et vous pouvez l'envelopper comme aide pour le DRY pour toujours
request.protocol + request.Host_with_port + Image.find(:first).image.url
Vous pouvez également définir le paramètre de configuration asset_Host
de CarrierWave comme suit:
# config/initializers/carrierwave.rb
CarrierWave.configure do |config|
config.storage = :file
config.asset_Host = ActionController::Base.asset_Host
end
Ceci ^ indique à CarrierWave d’utiliser le paramètre config.action_controller.asset_Host
de votre application, qui peut être défini dans l’un de vos fichiers config/envrionments/[environment].rb
. Voir ici pour plus d'informations.
Ou définissez-le explicitement:
config.asset_Host = 'http://example.com'
Redémarrez votre application et vous êtes prêt à partir - aucune méthode d'assistance n'est requise.
* J'utilise Rails 3.2 et CarrierWave 0.7.1
Une autre méthode simple à utiliser est URI.parse. Dans votre cas, ce serait:
require 'uri'
(URI.parse(root_url) + image.url).to_s
et quelques exemples:
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"
Prenant juste la réponse du parquet et fournissant l'aide
# 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
Il y a tout un tas de réponses ici. Cependant, je n’ai aimé aucun d’entre eux, car ils comptent tous sur moi pour rappeler d’ajouter explicitement le port, le protocole, etc. Je trouve que c’est la manière la plus élégante de procéder:
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
Et ce qui est bien, c'est que nous pouvons facilement changer une chose et peu importe la raison, vous le faites toujours de la même manière. Dites si vous voulez supprimer le protocole et que vous utilisez le RL relative au protocole , faites-le avant la conversion finale en chaîne.
full_url.scheme = nil
Oui, j’ai maintenant un moyen de convertir les URL de mon image d’immobilisation en URL du protocole que je peux utiliser dans un extrait de code que d’autres voudront peut-être ajouter sur leur site. Elles fonctionneront quel que soit le protocole utilisé sur leur site (à condition que votre site supporte l'un ou l'autre protocole).
J'ai utilisé default_url_options
, car request
n'est pas disponible dans le programme de messagerie et j'ai évité la duplication du nom d'hôte dans config.action_controller.asset_Host
si je ne l'avais pas spécifié auparavant.
config.asset_Host = ActionDispatch::Http::URL.url_for(ActionMailer::Base.default_url_options)
Vous ne pouvez pas faire référence à un objet de requête dans un courrier électronique.
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
Vous pouvez réellement y arriver facilement en
root_url[0..-2] + image.url
Je conviens que ça n'a pas l'air bien, mais que le travail est fait .. :)
J'ai trouvé cette astuce pour éviter le double slash:
URI.join(root_url, image.url)