J'ai une configuration de base d'ActiveStorage avec un modèle qui has_many_attached :file_attachments
. Dans un service ailleurs, j'essaie de générer un lien à utiliser en dehors de l'application principale (e-mail, travail, etc.).
Avec S3 en production, je peux faire: item.file_attachments.first.service_url
Et j'obtiens un lien approprié vers le bucket + objet S3.
Je ne peux pas utiliser la méthode prescrite dans les guides Rails: Rails.application.routes.url_helpers.Rails_blob_path(item.file_attachments.first)
Il contient des erreurs avec: ArgumentError: Missing Host to link to! Please provide the :Host parameter, set default_url_options[:Host], or set :only_path to true
Je peux lui passer un argument Host: 'http://....'
Et il est content même s'il ne génère toujours pas l'URL complète, juste le chemin.
En développement J'utilise le stockage de fichiers sur disque et je ne peux utiliser aucune des deux méthodes:
> Rails.application.routes.url_helpers.Rails_blob_path(item.file_attachments.first)
ArgumentError: Missing Host to link to! Please provide the :Host parameter, set default_url_options[:Host], or set :only_path to true
La définition d'hôte ici ne génère pas non plus d'URL complète.
En production, service_url
Fonctionne, mais ici en développement, je reçois l'erreur:
> item.file_attachments.first.service_url
ArgumentError: Missing Host to link to! Please provide the :Host parameter, set default_url_options[:Host], or set :only_path to true
et spécifier un hôte n'aide pas:
item.file_attachments.first.service_url(Host:'http://localhost.com')
ArgumentError: unknown keyword: Host
J'ai aussi essayé d'ajouter
config.action_mailer.default_url_options = { :Host => "localhost:3000" }
config.action_storage.default_url_options = { :Host => "localhost:3000" }
Rails.application.routes.default_url_options[:Host] = 'localhost:3000'
sans succès.
Ma question est - comment puis-je obtenir l'URL complète d'une manière qui fonctionne à la fois dans le développement et la production? ou où dois-je définir l'hôte?
Le service de disque d'Active Storage s'attend à trouver un hôte pour la génération d'URL dans ActiveStorage::Current.Host
.
Quand vous appelez ActiveStorage::Blob#service_url
manuellement, assurez-vous ActiveStorage::Current.Host
est défini. Si vous l'appelez depuis un contrôleur, vous pouvez sous-classer ActiveStorage::BaseController
. Si ce n'est pas une option, définissez ActiveStorage::Current.Host
dans un before_action
crochet:
class Items::FilesController < ApplicationController
before_action do
ActiveStorage::Current.Host = request.base_url
end
end
En dehors d'un contrôleur, utilisez ActiveStorage::Current.set
pour fournir un hôte:
ActiveStorage::Current.set(Host: "https://www.example.com") do
item.file_attachments.first.service_url
end