web-dev-qa-db-fra.com

ActiveStorage service_url && Rails_blob_path ne peut pas générer d'URL complète lorsque vous n'utilisez pas S3

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?

12
tgf

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
18
George Claghorn